让我们继续来练网络流;
很明显是一个最大流的问题;
二分枚举最多次数m,然后最大流判定;
具体就是男生女生都拆成两个点i1,i2,之间连一条流量为k的边(男生i1-->i2,女生i2-->i1);
i2连不喜欢的人,i1连喜欢的人
最后,男生i1连源点流量为m,女生i1连汇点流量为m
最后判断最大流是否等于n*m即可
但做着做着,我发现好像好像二分+最大流不是很优,因为进行了很多重复操作
但我也没管,先A了再说;
后来看status发现很多人代码很短,用时0ms(我的最大流180ms)
肯定有更简单的方法:
贪心!……其实是错的……
1 code(using maxflow): 2 type node=record 3 next,point,flow:longint; 4 end; 5 6 var edge:array[0..200010] of node; 7 a:array[0..60,0..60] of boolean; 8 cur,pre,p,numh,h:array[0..400] of longint; 9 j,m,n,k,i,len,t,ans,l,r:longint; 10 c:string; 11 12 function min(a,b:longint):longint; 13 begin 14 if a>b then exit(b) else exit(a); 15 end; 16 17 procedure add(x,y,f:longint); 18 begin 19 inc(len); 20 edge[len].flow:=f; 21 edge[len].point:=y; 22 edge[len].next:=p[x]; 23 p[x]:=len; 24 end; 25 26 function sap(m:longint):boolean; 27 var s,u,tmp,i,j,q:longint; 28 begin 29 len:=-1; 30 fillchar(p,sizeof(p),255); 31 for i:=1 to n do 32 begin 33 add(0,i,m); 34 add(i,0,m); 35 add(i+2*n,t,m); 36 add(t,i+2*n,0); 37 add(i,i+n,k); 38 add(i+n,i,0); 39 add(i+3*n,i+2*n,k); 40 add(i+2*n,i+3*n,0); 41 end; 42 for i:=1 to n do 43 for j:=1 to n do 44 if a[i,j] then 45 begin 46 add(i,j+2*n,1); 47 add(j+2*n,i,0); 48 end 49 else begin 50 add(i+n,j+3*n,1); 51 add(j+3*n,i+n,0); 52 end; 53 fillchar(numh,sizeof(numh),0); 54 fillchar(h,sizeof(h),0); 55 numh[0]:=t+1; 56 u:=0; 57 s:=0; 58 while h[0]<t+1 do 59 begin 60 if u=t then 61 begin 62 i:=0; 63 while i<>t do 64 begin 65 j:=cur[i]; 66 dec(edge[j].flow); 67 inc(edge[j xor 1].flow); 68 i:=edge[j].point; 69 end; 70 u:=0; 71 inc(s); 72 if s=n*m then exit(true); 73 end; 74 q:=-1; 75 i:=p[u]; 76 while i<>-1 do 77 begin 78 j:=edge[i].point; 79 if (edge[i].flow>0) and (h[u]=h[j]+1) then 80 begin 81 q:=i; 82 break; 83 end; 84 i:=edge[i].next; 85 end; 86 if q<>-1 then 87 begin 88 cur[u]:=q; 89 pre[j]:=u; 90 u:=j; 91 end 92 else begin 93 dec(numh[h[u]]); 94 if numh[h[u]]=0 then exit(false); 95 tmp:=t+1; 96 i:=p[u]; 97 while i<>-1 do 98 begin 99 j:=edge[i].point; 100 if edge[i].flow>0 then tmp:=min(tmp,h[j]); 101 i:=edge[i].next; 102 end; 103 h[u]:=tmp+1; 104 inc(numh[h[u]]); 105 if u<>0 then u:=pre[u]; 106 end; 107 end; 108 exit(false); 109 end; 110 111 begin 112 readln(n,k); 113 for i:=1 to n do 114 begin 115 readln(c); 116 for j:=1 to n do 117 begin 118 if c[j]='Y' then a[i,j]:=true 119 else a[i,j]:=false; 120 end; 121 end; 122 t:=n*4+1; 123 l:=1; 124 r:=n; 125 ans:=0; 126 while l<=r do 127 begin 128 m:=(l+r) shr 1; 129 if sap(m) then 130 begin 131 ans:=m; 132 l:=m+1; 133 end 134 else r:=m-1; 135 end; 136 writeln(ans); 137 end.