#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define INF 1000000 #define min(x,y) ((x)<(y)?(x):(y)) int ans,l,r,mid,n,k,s,t,tot,level[300],iter[300],head[300],q[3000]; char ch[100][100]; struct edge{int v,cap,rev,nxt;}E[80000]; void add(int x,int y,int k){ E[++tot].v=y; E[tot].cap=k; E[tot].rev=tot+1; E[tot].nxt=head[x]; head[x]=tot; E[++tot].v=x; E[tot].cap=0; E[tot].rev=tot-1; E[tot].nxt=head[y]; head[y]=tot; } void bfs(int s){ memset(level,-1,sizeof level); level[s]=0; int tt=0,ww=1; q[1]=s; while (tt<ww){ tt++; int v=q[tt]; for (int i=head[v];i;i=E[i].nxt){ edge &e=E[i]; if (e.cap>0 && level[e.v]<0){ level[e.v]=level[v]+1; q[++ww]=e.v; } } } } int dfs(int v,int t,int f){ if (v==t) return f; for (int &i=iter[v];i;i=E[i].nxt){ edge &e=E[i]; if (e.cap>0 && level[v]<level[e.v]){ int d=dfs(e.v,t,min(f,e.cap)); if (d>0){ e.cap-=d; E[e.rev].cap+=d; return d; } } } return 0; } int max_flow(int s,int t){ int flow=0; for (;;){ bfs(s); if (level[t]<0) break; for (int i=1;i<=n*5+2;i++) iter[i]=head[i]; int f=0; while ((f=dfs(s,t,INF))>0) flow+=f; } return flow; } void build(int x){ tot=0; memset(head,0,sizeof head); for (int i=1;i<=n;i++){ add(s,i,x); add(i,i+n,k); add(i+n*2,t,x); add(i+n*3,i+n*2,k); } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (ch[i][j]=='Y') add(i,j+n*2,1); else add(i+n,j+n*3,1); } int main(){ scanf("%d%d\n",&n,&k); s=n*5+1; t=n*5+2; for (int i=1;i<=n;i++) gets(ch[i]+1); l=0; r=n; while (l<=r){ mid=(l+r)>>1; build(mid); if (max_flow(s,t)==mid*n){ans=mid; l=mid+1;} else r=mid-1; } printf("%d\n",ans); return 0; }
|