bzoj1433: [ZJOI2009]假期的宿舍 [二分图][二分图最大匹配]
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。
最近被二分图到底要用邻接矩阵还是邻接表搞得十分分裂。。
还是看图的稠密程度吧???
这题的建图十分经典,对于每一个本校学生对自己的床连边,其他连边同输入的矩阵。
本质虽然是匈牙利算法求二分图最大匹配,事实上不用把最大匹配求出来,只要增广到对于一个需要住校的人没有床睡就好了。
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 }