BZOJ 1433: [ZJOI2009]假期的宿舍
标签(空格分隔): OI-BZOJ OI-二分图匹配
Time Limit: 10 Sec
Memory Limit: 162 MB
Description
Input
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;
}