bzoj1433: [ZJOI2009]假期的宿舍 [二分图][二分图最大匹配]

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。

 


 

最近被二分图到底要用邻接矩阵还是邻接表搞得十分分裂。。

还是看图的稠密程度吧???

这题的建图十分经典,对于每一个本校学生对自己的床连边,其他连边同输入的矩阵。

本质虽然是匈牙利算法求二分图最大匹配,事实上不用把最大匹配求出来,只要增广到对于一个需要住校的人没有床睡就好了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 const int maxn=55;
 7 int T,n,n_l,n_r;
 8 int E[maxn][maxn],stu[maxn],hom[maxn],mat[maxn];
 9 bool check[maxn];
10 
11 bool dfs(int x){
12     for(int i=1;i<=n_r;i++)
13         if(stu[i]&&E[x][i]&&!check[i]){
14             check[i]=1;
15             if(mat[i]==-1||dfs(mat[i])){
16                 mat[i]=x;
17                 return 1;
18             }
19         }
20     return 0;
21 }
22 
23 bool hungary(){
24     memset(mat,-1,sizeof mat);
25     for(int i=1;i<=n;i++){
26         memset(check,0,sizeof check);
27         if(!hom[i]&&!dfs(i))  return 0;
28     }
29     return 1;
30 }
31 
32 void init(){
33     scanf("%d",&n);  n_l=n_r=n;
34     for(int i=1;i<=n;i++)  scanf("%d",&stu[i]);
35     for(int i=1;i<=n;i++){
36         scanf("%d",&hom[i]);
37         if(!stu[i])  hom[i]=0;
38     }
39     for(int i=1;i<=n;i++){
40         for(int j=1;j<=n;j++)
41             scanf("%d",&E[i][j]);
42         if(stu[i])  E[i][i]=1;
43     }
44 }
45 
46 int main(){
47     scanf("%d",&T);
48     while(T--){
49         init();
50         puts(hungary()?"^_^":"T_T");
51     }
52     return 0;
53 }

 

posted @ 2017-07-30 16:15  ZYBGMZL  阅读(109)  评论(0编辑  收藏  举报