Http://hzwer.com/1986.html
#include <cstdio> #include <algorithm> #include <queue> #include <cstring>using namespace std;# Define INF 2147483647#define N 51int n,m;char a[n][n];queue<int>q;int s,t,nn;int first[(n<<2) +3],next[2*N* (n+5)],v[2*n* (n+5)],cap[2*n* (n+5)],en;int d[(n<<2) +3],cur[(n<<2) +3];void addedge (int U,int V,int cap) {V [En]=v; Cap[en]=cap; Next[en]=first[u]; First[u]=en++;v[en]=u; cap[en]=0; NEXT[EN]=FIRST[V]; first[v]=en++;} BOOL BFs () {memset (d,-1,sizeof (int) * (nn+1)); Q.push (S); D[s]=0;while (!q.empty ()) {int U=q.front (); Q.pop (); for (int i=first[u];i!=-1;i=next[i]) if (D[v[i]]==-1&&cap[i]) {d[v[i]]=d[u]+1; Q.push (V[i]); }}return d[t]!=-1;} int dfs (int u,int a) {if (u==t| | (!a)) return a;int flow=0,f;for (int i=first[u];i!=-1;i=next[i]) if (d[v[i]]==d[u]+1&& (F=dfs (v[i],min)))) {cap[i]-=f; Cap[i^1]+=f; Flow+=f; A-=f; if (!a) break; }if (! flow) D[u]=-1;return flow;} int Maxflow() {int flow=0,tmp;while (BFS ()) {memcpy (cur,first,sizeof (int) * (nn+1)); while (Tmp=dfs (S,inf)) flow+=tmp; }return Flow;} BOOL Check (int Lim) {memset (first,-1,sizeof (int) * (nn+1)); en=0;for (int i=1;i<=n;++i) {Addedge (S,1+i,lim); Addedge (1+ (n<<1) +i,t,lim); Addedge (1+I,1+N+I,M); Addedge (1+n*3+i,1+ (n<<1) +i,m); }for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) if (a[i][j]== ' Y ') Addedge (1+i,1+ (n<<1) +j,1); else Addedge (1+n+i,1+n*3+j,1); return Maxflow () ==n*lim;} int main () {scanf ("%d%d", &n,&m), for (int i=1;i<=n;++i) scanf ("%s", a[i]+1); int l=0,r=50; S=1; t= (n<<2) +2; Nn= (n<<2) +2;while (r>l) {int mid= (l+r+1>>1); if (check (mid)) L=mid; else r=mid-1; }printf ("%d\n", l); return 0;}
Two-point answer, maximum flow bzoj1305 [Cqoi2009]dance dance