1433: [ZJOI2009]假期的宿舍
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1717 Solved: 754
[Submit][Status][Discuss]
Description
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。
Source
【思路】
最大流。
构图:
1 每个人建立两个点u1,u2,建立s t点。
2 如果需要床则s向u1连边,如果有床u2向t连边,如果认识u1向v2连边。
Ps:总而言之,建图的思路就是要分配已有的床给需要床的人。
【代码】
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<vector> 5 #define FOR(a,b,c) for(int a=(b);a<(c);a++) 6 using namespace std; 7 8 const int maxn = 500+10; 9 const int INF = 1e9; 10 11 struct Edge{ 12 int u,v,cap,flow; 13 }; 14 struct Dinic { 15 int n,m,s,t; 16 bool vis[maxn]; 17 int d[maxn],cur[maxn]; 18 vector<int> G[maxn]; 19 vector<Edge> es; 20 21 void init(int n) { 22 this->n=n; 23 es.clear(); 24 for(int i=0;i<n;i++) G[i].clear(); 25 } 26 void AddEdge(int u,int v,int cap) { 27 es.push_back((Edge){u,v,cap,0}); 28 es.push_back((Edge){v,u,0,0}); 29 m=es.size(); 30 G[u].push_back(m-2); 31 G[v].push_back(m-1); 32 } 33 34 bool BFS() { 35 queue<int> q; 36 memset(vis,0,sizeof(vis)); 37 q.push(s); vis[s]=1; d[s]=0; 38 while(!q.empty()) { 39 int u=q.front(); q.pop(); 40 for(int i=0;i<G[u].size();i++) { 41 Edge& e=es[G[u][i]]; 42 int v=e.v; 43 if(!vis[v] && e.cap>e.flow) { 44 vis[v]=1; 45 d[v]=d[u]+1; 46 q.push(v); 47 } 48 } 49 } 50 return vis[t]; 51 } 52 int DFS(int u,int a) { 53 if(u==t || a==0) return a; 54 int flow=0,f; 55 for(int& i=cur[u];i<G[u].size();i++){ 56 Edge& e=es[G[u][i]]; 57 int v=e.v; 58 if( d[v]==d[u]+1 && (f=DFS(v,min(a,e.cap-e.flow)))>0 ) { 59 e.flow+=f; 60 es[G[u][i]^1].flow-=f; 61 flow+=f,a-=f; 62 if(!a) break; 63 } 64 } 65 return flow; 66 } 67 int Maxflow(int s,int t) { 68 this->s=s , this->t=t; 69 int flow=0; 70 while(BFS()) { 71 memset(cur,0,sizeof(cur)); 72 flow+=DFS(s,INF); 73 } 74 return flow; 75 } 76 } dc; 77 78 int n,m; 79 int f[maxn]; 80 81 int main() { 82 int T; 83 scanf("%d",&T); 84 while(T--) { 85 scanf("%d",&n); 86 dc.init(n*2+2); 87 int s=n*2,t=s+1; 88 FOR(i,0,n) { 89 scanf("%d",&f[i]); 90 if(f[i]) dc.AddEdge(i+n,t,1); 91 } 92 int x,sum=0; 93 FOR(i,0,n) { 94 scanf("%d",&x); 95 if((f[i]&&!x) || (!f[i])) { 96 dc.AddEdge(s,i,1); 97 sum++; 98 } 99 } 100 FOR(i,0,n) FOR(j,0,n) { 101 scanf("%d",&x); 102 if(x || i==j) dc.AddEdge(i,j+n,1); 103 } 104 int flow=dc.Maxflow(s,t); 105 if(flow==sum) printf("^_^ "); 106 else printf("T_T "); 107 } 108 return 0; 109 }