1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include<iostream> #include<cstdio> #include<cstring> #include<queue> #define ll long long using namespace std;
const ll inf=1e13,N=3e2,M=5e3;
ll n,k,tot,s,t,cnt; ll ver[M*2+5],nxt[M*2+5],head[N+5],wt[M*2+5]; ll d[N+5],now[N+5]; ll u[M+5],v[M+5]; char ss[N+5]; queue<ll> q;
inline bool BFS() { memset(d,0,sizeof(d)); while(!q.empty()) q.pop(); q.push(s);d[s]=1;now[s]=head[s]; while(!q.empty()) { ll h=q.front();q.pop(); for(ll i=head[h];i;i=nxt[i]) { if(!wt[i]||d[ver[i]]) continue; q.push(ver[i]); now[ver[i]]=head[ver[i]]; d[ver[i]]=d[h]+1; if(ver[i]==t) return 1; } } return 0; }
inline ll Dinic(ll x,ll flow) { if(x==t) return flow; ll rest=flow,k,i; for(i=now[x];i&&rest;i=nxt[i]) { if(!wt[i]||d[ver[i]]!=d[x]+1) continue; k=Dinic(ver[i],min(rest,wt[i])); if(!k) d[ver[i]]=0; wt[i]-=k;wt[i^1]+=k;rest-=k; if(rest==0) return flow-rest; } now[x]=i;return flow-rest; }
inline void Addedge(ll u,ll v,ll w) { ver[++tot]=v;wt[tot]=w;nxt[tot]=head[u];head[u]=tot; ver[++tot]=u;wt[tot]=0;nxt[tot]=head[v];head[v]=tot; }
inline bool Check(ll x) { memset(ver,0,sizeof(ver)); memset(nxt,0,sizeof(nxt)); memset(head,0,sizeof(head)); memset(wt,0,sizeof(wt)); tot=1; for(ll i=1;i<=n;i++) {Addedge(s,i,x);} for(ll i=1;i<=n;i++) {Addedge(2*n+i,t,x);} for(ll i=1;i<=n;i++) {Addedge(i,n+i,k);} for(ll i=1;i<=n;i++) {Addedge(3*n+i,2*n+i,k);} for(ll i=1;i<=cnt;i++) {Addedge(u[i],v[i],1);} ll flow=0,maxflow=0; while(BFS()) {while(flow=Dinic(s,inf)) maxflow+=flow;} if(maxflow>=n*x) return 1;return 0; }
inline ll read() { ll ret=0,f=1;char ch=getchar(); while(ch<48||ch>57) {if(ch==45) f=-f;ch=getchar();} while(ch>=48&&ch<=57) {ret=(ret<<3)+(ret<<1)+ch-48;ch=getchar();} return ret*f; }
inline void write(ll x) { static char buf[22];static ll len=-1; if(x>=0) {do{buf[++len]=x%10+48;x/=10;}while(x);} else {putchar(45);do{buf[++len]=-(x%10)+48;x/=10;}while(x);} while(len>=0) putchar(buf[len--]); }
int main() {
n=read();k=read();s=n*4+1;t=n*4+2;
for(ll i=1;i<=n;i++) { scanf("%s",ss+1); for(ll j=1;j<=n;j++) { if(ss[j]=='Y') {u[++cnt]=i;v[cnt]=j+2*n;} if(ss[j]=='N') {u[++cnt]=n+i;v[cnt]=j+3*n;} } }
ll l=0,r=n*n; while(l<r) { ll mid=(l+r+1)>>1; if(Check(mid)) l=mid; else r=mid-1; }
write(l);
return 0; }
|