bzoj1433 [ZJOI2009]假期的宿舍 最大流

[ZJOI2009]假期的宿舍

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3429  Solved: 1459
[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

Sample Output

ˆ ˆ

HINT

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

 

源点向所有有床位的连边

需要床位的向汇点连边

如果i可以睡j的床

i向j‘连边

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define T 101
 5 #define inf 0x7fffffff
 6 using namespace std;
 7 int sc[51];
 8 int n,tot,cnt=1,ans,head[105],h[105];
 9 struct data{int to,next,v;}e[50001];
10 void ins(int u,int v,int w)
11 {cnt++;e[cnt].to=v;e[cnt].v=w;e[cnt].next=head[u];head[u]=cnt;}
12 void insert(int u,int v,int w)
13 {ins(u,v,w);ins(v,u,0);}
14 bool bfs()
15 {
16      int q[105],t=0,w=1,i,now;
17      memset(h,-1,sizeof(h));
18      q[0]=h[0]=0;
19      while(t!=w)
20      {
21             now=q[t];t++;if(t==101)t=0;
22             i=head[now];
23             while(i)
24             {
25                   if(e[i].v&&h[e[i].to]<0)
26                         {h[e[i].to]=h[now]+1;q[w++]=e[i].to;if(w==101)w=0;}
27                   i=e[i].next;
28              }
29      }
30      if(h[T]==-1)return 0;
31      return 1;
32      }
33 int dfs(int x,int f)
34 {
35     if(x==T)return f;
36     int i=head[x],w,used=0;
37     while(i)
38     {
39             if(e[i].v&&h[e[i].to]==h[x]+1)
40             {
41                 w=f-used;
42                 w=dfs(e[i].to,min(w,e[i].v));   
43                 e[i].v-=w;
44                 e[i^1].v+=w;
45                 used+=w;
46                 if(used==f)return f;                      
47                 }
48                 i=e[i].next;
49             }
50     if(!used)h[x]=-1;
51     return used;
52     }
53 void dinic(){while(bfs())ans+=dfs(0,inf);}
54 int main()
55 {
56     int test;scanf("%d",&test);
57     while(test--)
58     {
59         tot=ans=0;cnt=1;
60         memset(head,0,sizeof(head));
61         scanf("%d",&n);
62         for(int i=1;i<=n;i++)
63         {
64             scanf("%d",&sc[i]);
65             if(sc[i])
66                 insert(i+n,T,1);//如果是在校学生,则有床位 
67         }
68         int x;
69         for(int i=1;i<=n;i++)
70         {
71             scanf("%d",&x);
72             if((sc[i]&&!x)||!sc[i]) 
73             {
74                 insert(0,i,1);//不回家或者外校的需要床 
75                 tot++;
76             }
77         }
78         for(int i=1;i<=n;i++)
79            for(int j=1;j<=n;j++)
80            {
81                   scanf("%d",&x);
82                   if(x||i==j)insert(i,j+n,1);//可以睡的床 
83            }
84         dinic();
85         if(ans==tot)puts("^_^");
86         else puts("T_T");
87     }
88     return 0;
89 }

 

posted @ 2018-01-15 09:51  Kaiser-  阅读(124)  评论(0编辑  收藏  举报