首先考虑二维的情况
min(x,y)也就意味着确定最小后,另外一维肯定打满
然后最小那个如果是k的话就相当于用k*1次——这不就是行列覆盖吗,二分图秒之
三维呢?考虑到a*b*c<=5000也就是最小的那维不超过17
那么我们直接穷举那维用哪些,然后另外的就跟二维一样了
注意要优化常数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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.