边数(4n+n^2)*2
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<iostream> #define inf 1000000000 #define maxn 310 #define maxm 12010 using namespace std; int head[maxn],to[maxm],next[maxm],c[maxm],q[maxn],d[maxn]; int n,m,num,s,t,k; char s1[maxn]; int a[maxn][maxn]; void addedge(int x,int y,int z) { num++;to[num]=y;c[num]=z;next[num]=head[x];head[x]=num; num++;to[num]=x;c[num]=0;next[num]=head[y];head[y]=num; } bool bfs() { memset(d,-1,sizeof(d)); int l=0,r=1; q[1]=s;d[s]=0; while (l<r) { int x=q[++l]; for (int p=head[x];p;p=next[p]) if (c[p] && d[to[p]]==-1) { d[to[p]]=d[x]+1; q[++r]=to[p]; } } if (d[t]==-1) return 0; else return 1; } int find(int x,int low) { if (x==t || low==0) return low; int totflow=0; for (int p=head[x];p;p=next[p]) if (c[p] && d[to[p]]==d[x]+1) { int a=find(to[p],min(low,c[p])); c[p]-=a;c[p^1]+=a; totflow+=a;low-=a; if (low==0) return totflow; } if (low) d[x]=-1; return totflow; } bool Dinic(int x) { num=1; memset(head,0,sizeof(head)); memset(c,0,sizeof(c)); s=0;t=4*n+1; for (int i=1;i<=n;i++) addedge(s,i,x),addedge(i,n+i,k),addedge(2*n+i,3*n+i,k),addedge(3*n+i,t,x); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (a[i][j]) addedge(i,3*n+j,1); else addedge(n+i,2*n+j,1); int ans=0; while (bfs()) ans+=find(s,inf); if (ans==n*x) return 1; else return 0; } int main() { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) { scanf("%s",s1+1); for (int j=1;j<=n;j++) if (s1[j]=='Y') a[i][j]=1; else a[i][j]=0; } int l=1,r=n,ans=0; while (l<=r) { int mid=(l+r)/2; if (Dinic(mid)) l=mid+1,ans=mid; else r=mid-1; } printf("%d\n",ans); return 0; }