bzoj3140

首先考虑二维的情况

min(x,y)也就意味着确定最小后,另外一维肯定打满

然后最小那个如果是k的话就相当于用k*1次——这不就是行列覆盖吗,二分图秒之

三维呢?考虑到a*b*c<=5000也就是最小的那维不超过17

那么我们直接穷举那维用哪些,然后另外的就跟二维一样了

注意要优化常数

  1 type node=record
  2        po,next:longint;
  3      end;
  4 
  5 var e:array[0..200010] of node;
  6     d:array[0..5010,1..3] of longint;
  7     p,cx,cy:array[0..5010] of longint;
  8     v:array[0..5010] of boolean;
  9     can,f:array[0..18] of boolean;
 10     x,tt,j,k,len,ans,i,t,a,b,c,a0,b0,c0:longint;
 11 
 12 function max(a,b:longint):longint;
 13   begin
 14     if a>b then exit(a) else exit(b);
 15   end;
 16 
 17 procedure add(x,y:longint);
 18   begin
 19     inc(len);
 20     e[len].po:=y;
 21     e[len].next:=p[x];
 22     p[x]:=len;
 23   end;
 24 
 25 procedure swap(var a,b:longint);
 26   var c:longint;
 27   begin
 28     c:=a;
 29     a:=b;
 30     b:=c;
 31   end;
 32 
 33 function dfs(x:longint):longint;
 34   var i,y:longint;
 35   begin
 36     i:=p[x];
 37     while i<>0 do
 38     begin
 39       y:=e[i].po;
 40       if not v[y] then
 41       begin
 42         v[y]:=true;
 43         if (cy[y]=-1) or (dfs(cy[y])=1) then
 44         begin
 45           cy[y]:=x;
 46           cx[x]:=y;
 47           exit(1);
 48         end;
 49       end;
 50       i:=e[i].next;
 51     end;
 52     exit(0);
 53   end;
 54 
 55 function cal(s:longint):longint;
 56   var i,j:longint;
 57   begin
 58     cal:=s;
 59     len:=0;
 60     for i:=1 to b do
 61     begin
 62       p[i]:=0;
 63       cx[i]:=-1;
 64     end;
 65     for i:=1 to c do
 66       cy[i]:=-1;
 67     for i:=1 to t do
 68       if not f[d[i,a0]] then
 69         add(d[i,b0],d[i,c0]);
 70     for i:=1 to b do
 71       if cx[i]=-1 then
 72       begin
 73         for j:=1 to c do
 74           v[j]:=false;
 75         cal:=cal+dfs(i);
 76         if cal>=ans then exit;
 77       end;
 78   end;
 79 
 80 procedure work(x,s:longint);
 81   var m:longint;
 82   begin
 83     if s>=ans then exit;
 84     if x=a+1 then
 85     begin
 86       m:=cal(s);
 87       if m<ans then ans:=m;
 88     end
 89     else begin
 90       f[x]:=false;
 91       work(x+1,s);
 92       if can[x] then
 93       begin
 94         f[x]:=true;
 95         work(x+1,s+1);
 96         f[x]:=false;
 97       end;
 98     end;
 99   end;
100 
101 begin
102   readln(tt);
103   while tt>0 do
104   begin
105     dec(tt);
106     readln(a,b,c);
107     a0:=1; b0:=2; c0:=3;
108     t:=0;
109     for i:=1 to a do
110       for j:=1 to b do
111         for k:=1 to c do
112         begin
113           read(x);
114           if x=1 then
115           begin
116             inc(t);
117             d[t,1]:=i;
118             d[t,2]:=j;
119             d[t,3]:=k;
120           end;
121         end;
122     if (b<=a) and (b<=c) then
123     begin
124       swap(a0,b0);
125       swap(a,b);
126     end
127     else if (c<=a) and (c<=b) then
128     begin
129       swap(a0,c0);
130       swap(a,c);
131     end;
132     if b>c then
133     begin
134       swap(b0,c0);
135       swap(b,c);
136     end;
137     fillchar(can,sizeof(can),false);
138     for i:=1 to t do
139       can[d[i,a0]]:=true;
140     ans:=0;
141     for i:=1 to a do
142       if can[i] then inc(ans);
143     fillchar(f,sizeof(f),false);
144     work(1,0);
145     writeln(ans);
146   end;
147 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4590703.html