bzoj 1433: [ZJOI2009]假期的宿舍 -- 最大流
1433: [ZJOI2009]假期的宿舍
Time Limit: 10 Sec Memory Limit: 162 MBDescription
Input
Output
Sample Input
1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
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。
我们从源点向所有住宿的人连边,从所有的床位连向汇点,然后再从人连向他所认识的人的床位
这样建边,然后跑最大流
这样答案如果和住宿人数相等则满足,否则不满足
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define inf 100007 #define F(i) for(i=1;i<=n;i++) #define N 50010 #define M 110 inline int rd() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int lj[M],fro[N],to[N],cnt,v[N],S,T=101; inline void add(int a,int b,int c){fro[++cnt]=lj[a];to[cnt]=b;v[cnt]=c;lj[a]=cnt;} inline void ins(int a,int b,int c){add(a,b,c);add(b,a,0);} int dis[M],q[N],h,t; bool bfs() { memset(dis,0,sizeof(dis)); dis[0]=h=t=1;q[1]=0; int tp; while(h<=t) { tp=q[h++]; for(int i=lj[tp];i;i=fro[i]) { if(!dis[to[i]]&&v[i]) { dis[to[i]]=dis[tp]+1; q[++t]=to[i]; } } } return dis[T]?1:0; } int dfs(int x,int p) { if(x==T) return p; int tp,res=0; for(int i=lj[x];i;i=fro[i]) { if(v[i]&&dis[to[i]]==dis[x]+1) { tp=dfs(to[i],min(p-res,v[i])); v[i]-=tp; v[i^1]+=tp; res+=tp; if(res==p) return p; } } if(res==0) dis[x]=0; return res; } int n,tt,sc[M],tot,ans; int main() { tt=rd(); int i,j,x; while(tt--) { tot=ans=0; memset(lj,0,sizeof(lj));cnt=1; n=rd(); F(i){ sc[i]=rd(); if(sc[i]) ins(i+n,T,1); } F(i){ x=rd(); if((sc[i]&&!x)||!sc[i]) { ins(0,i,1); tot++; } } F(i) F(j) { x=rd(); if(x||i==j) ins(i,j+n,1); } while(bfs()) ans+=dfs(0,inf); if(tot==ans) puts("^_^"); else puts("T_T"); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。