洛谷2055 假期的宿舍(網路流)
阿新 • • 發佈:2018-10-31
最近氵谷怎麼一直推網路流。。。
【題目分析】
良心的資料範圍,肯定就是O()的玩意兒了,emmm,網路流!
因為題目中給出了許多關係,最後詢問是否能全部解決,那麼就相當於給了匹配關係,詢問最大匹配數與總數之間的關係,所以網路流的解法就出來了。
對於每個非在校學生和要回家的學生,肯定就不需要考慮他們了,將他們與s連容量為1的邊限制最多1個人,對於每個住校學生,肯定需要床,那麼就將自己的床與t連容量為1的邊,因為自己可以睡自己的床,那麼和自己的床連邊。再讀入人和人的關係,如果為1就將這個人和那個人的床連容量為1的邊。
最後跑一遍最大流詢問最大匹配數,如果最大匹配數小於住校學生數,那麼就不可以,否則可以。
PS:記得初始化。。。。。。
【程式碼~】
#include<bits/stdc++.h> using namespace std; const int MAXN=201; const int MAXM=1e4+10; const int INF=0x3f3f3f3f; int n,m,cnt,s,t,total; int head[MAXN],cur[MAXN],depth[MAXN]; int nxt[MAXM],to[MAXM],w[MAXM]; int stu[MAXN],hom[MAXN]; int Read() { int i=0,f=1; char c; for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar()); if(c=='-') f=-1,c=getchar(); for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0'; return i*f; } void Add(int x,int y,int z) { nxt[cnt]=head[x]; head[x]=cnt; to[cnt]=y; w[cnt]=z; cnt++; } void add(int x,int y,int z) { Add(x,y,z); Add(y,x,0); } bool bfs() { memset(depth,0,sizeof(depth)); queue<int> q; depth[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=nxt[i]) { int v=to[i]; if(!depth[v]&&w[i]) { depth[v]=depth[u]+1; q.push(v); } } } return depth[t]!=0; } int dfs(int u,int flow) { if(u==t) return flow; for(int &i=cur[u];i!=-1;i=nxt[i]) { int v=to[i]; if(depth[v]==depth[u]+1&&w[i]) { int di=dfs(v,min(w[i],flow)); if(di>0) { w[i]-=di; w[i^1]+=di; return di; } } } return 0; } int dinic() { int ans=0; while(bfs()) { for(int i=0;i<=t;++i) cur[i]=head[i]; while(int d=dfs(s,INF)) ans+=d; } return ans; } int main() { int T=Read(); while(T--) { cnt=0,total=0; memset(head,-1,sizeof(head)); memset(stu,0,sizeof(stu)); memset(hom,0,sizeof(hom)); n=Read(); s=0,t=n+n+1; for(int i=1;i<=n;++i) stu[i]=Read(); for(int i=1;i<=n;++i) hom[i]=Read(); for(int i=1;i<=n;++i) { if(!stu[i]||(stu[i]&&!hom[i])) add(s,i,1),total++; if(stu[i]) add(i+n,t,1); } for(int i=1;i<=n;++i) { if(stu[i]&&!hom[i]) add(i,i+n,1); for(int j=1;j<=n;++j) { int x=Read(); if(x) add(i,j+n,1); } } if(dinic()==total) puts("^_^"); else puts("T_T"); } return 0; }