BZOJ 1433: [ZJOI2009]假期的宿舍

BZOJ 1433: [ZJOI2009]假期的宿舍

标签(空格分隔): OI-BZOJ OI-二分图匹配

Time Limit: 10 Sec
Memory Limit: 162 MB

Description
BZOJ 1433: [ZJOI2009]假期的宿舍_第1张图片

Input
BZOJ 1433: [ZJOI2009]假期的宿舍_第2张图片

Output
此处输入图片的描述

Sample Input

1

3

1 1 0

0 1 0

0 1 1

1 0 0

1 0 0
Sample Output

ˆ_ˆ

HINT

对于30% 的数据满足1 ≤ n ≤ 12。
对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。

Solution

二分图匹配

Code

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
int read()
{
    int s=0,f=1;char ch=getchar();
    while(!('0'<=ch&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}
    while('0'<=ch&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
    return s*f;
}
int S,T,n,m,np,TT;
int A[305],B[305];
int be[100005],bn[200005],bv[200005],bl[200005],bw=1;
void put(int u,int v,int l)
{bw++;bn[bw]=be[u];be[u]=bw;bv[bw]=v;bl[bw]=l;}
int d[100005];
bool spfa(int S,int T)
{
    for(int i=1;i<=np;i++)
       d[i]=10000000;
    d[S]=1;
    queue<int>q;
    for(q.push(S);!q.empty();)
       {int u=q.front();q.pop();
        for(int i=be[u],v;i;i=bn[i])
           if(d[v=bv[i]]>d[u]+1&&bl[i])
             {d[v]=d[u]+1;
              q.push(v);
             }
       }
    return d[T]!=10000000;
}
int ans,sum;
int dinic(int u,int mf,int T)
{
    if(mf==0)return 0;
    if(u==T)return mf;
    int sum=0;
    for(int i=be[u],v;i;i=bn[i])
       if(d[v=bv[i]]==d[u]+1)
         {int f=dinic(v,min(mf-sum,bl[i]),T);
          bl[i]-=f;
          bl[i^1]+=f;
          sum+=f;
         }
    return sum;
}
int p[55];
int main()
{
    for(TT=read();TT--;)
       {for(int i=1;i<=np;i++)be[i]=0;
        bw=1;np=ans=sum=0;
        n=read();
        for(int i=1;i<=n;i++)B[i]=++np;
        for(int i=1;i<=n;i++)A[i]=++np;
        S=++np,T=++np;
        for(int i=1;i<=n;i++)
            if(p[i]=read())
              put(B[i],T,1),
              put(T,B[i],0);
        for(int i=1,x;i<=n;i++)
           {x=read();
            if((!x&&p[i])|!p[i])
              put(S,A[i],1),
              put(A[i],S,0),
              sum++;
           }
        for(int i=1;i<=n;i++)
           {for(int j=1;j<=n;j++)
                if(read()||i==j)
                   {put(A[i],B[j],1),
                    put(B[j],A[i],0);
                   }
           }
        while(spfa(S,T))ans+=dinic(S,1e9,T);
        puts(sum==ans?"^_^":"T_T");
       }
    return 0;
}

你可能感兴趣的:(BZOJ 1433: [ZJOI2009]假期的宿舍)