1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #define M 1000
  5 #define inf 0x7fffffff
  6 using namespace std;
  7 int T,n,k,sum,cnt=1,head[M],next[10*M],u[10*M],v[10*M],d[2*M],q[2*M],mp[M][M];
  8 char ch[66];
  9 void jia(int a1,int a2,int a3)
 10 {
 11     cnt++;
 12     u[cnt]=a2;
 13     v[cnt]=a3;
 14     next[cnt]=head[a1];
 15     head[a1]=cnt;
 16     return;
 17 }
 18 bool bfs()
 19 {
 20     memset(d,0,sizeof(int)*(T+2));
 21     int h=0,t=1;
 22     q[1]=0;
 23     d[0]=1;
 24     for(;h<t;)
 25       {
 26         h++;
 27         int p=q[h];
 28         for(int i=head[p];i;i=next[i])
 29           if(!d[u[i]]&&v[i])
 30             {
 31                 d[u[i]]=d[p]+1;
 32                 if(d[T])
 33                   return 1;
 34                 t++;
 35                 q[t]=u[i];
 36             }
 37       }
 38     return 0;
 39 }
 40 int dinic(int s,int f)
 41 {
 42     if(s==T)
 43       return f;
 44     int rest=f;
 45     for(int i=head[s];i&&rest;i=next[i])
 46       if(v[i]&&d[u[i]]==d[s]+1)
 47         {
 48             int now=dinic(u[i],min(rest,v[i]));
 49             if(!now)
 50               d[u[i]]=0;
 51             v[i]-=now;
 52             v[i^1]+=now;
 53             rest-=now;
 54         }
 55     return f-rest;  
 56 }
 57 bool pan(int a1)
 58 {
 59     memset(head,0,sizeof(head));
 60     cnt=1;
 61     for(int i=1;i<=n;i++)
 62       {
 63         jia(0,i,a1);
 64         jia(i,0,0);
 65         jia(i,n+i,k);
 66         jia(n+i,i,0);
 67         jia(3*n+i,T,a1);
 68         jia(T,3*n+i,0);
 69         jia(2*n+i,3*n+i,k);
 70         jia(3*n+i,2*n+i,0);
 71       }
 72     for(int i=1;i<=n;i++)
 73       for(int j=1;j<=n;j++)
 74         if(mp[i][j])
 75           {
 76             jia(i,3*n+j,1);
 77             jia(3*n+j,i,0);
 78           }
 79         else
 80           {
 81             jia(n+i,2*n+j,1);
 82             jia(2*n+j,n+i,0);
 83           }
 84     sum=0;
 85     for(;bfs();)
 86       sum+=dinic(0,inf);
 87     if(sum<a1*n)
 88       return 0;
 89     return 1;
 90 }
 91 int main()
 92 {
 93     scanf("%d%d",&n,&k);
 94     T=(4*n)+1;
 95     for(int i=1;i<=n;i++)
 96       {
 97         scanf("%s",ch+1);
 98         for(int j=1;j<=n;j++)
 99           if(ch[j]=='Y')
100             mp[i][j]=1;
101       }
102     int l=0,r=50,ans=0;
103     for(;l<=r;)
104       {
105         int mid=(l+r)>>1;
106         if(pan(mid))
107           {
108             l=mid+1;
109             ans=l;
110             }
111         else
112           r=mid-1;
113       }
114     printf("%d\n",ans-1);
115     return 0;
116 }

网络流  将男女进行拆点,二分答案,同一个人之间建容量k的边,源汇分别向男女连mid的边,再根据喜欢不喜欢对男女进行连边,使如果不喜欢的话要走同一个人之间的那一条边,最后

观察一下是否满流。

posted on 2016-03-12 23:01  xiyuedong  阅读(185)  评论(0编辑  收藏  举报