bzoj 1433: [ZJOI2009]假期的宿舍

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

网络流 首先源点向所有要住的人连边,床向汇点连边,人向能睡的床连边,然后跑最大流,看是否满流即可。

原文地址:https://www.cnblogs.com/xydddd/p/5271173.html