1. 程式人生 > >[BZOJ1433][ZJOI2009]假期的宿舍 二分圖匹配

[BZOJ1433][ZJOI2009]假期的宿舍 二分圖匹配

std getc als zjoi blog mes read string space

題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1433

首先留在學校的學生向自己的床連邊。

要住在學校裏的人向認識的學生的床連邊。

跑二分圖匹配,看匹配的數量是否等於住在學校的人數。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int inline readint(){
 6     int Num;char ch;
 7     while((ch=getchar())<
0||ch>9);Num=ch-0; 8 while((ch=getchar())>=0&&ch<=9) Num=Num*10+ch-0; 9 return Num; 10 } 11 int N; 12 bool A[55],B[55]; 13 int to[2510],ne[2510],fir[110],cnt; 14 void Add(int a,int b){ 15 to[++cnt]=b; 16 ne[cnt]=fir[a]; 17 fir[a]=cnt; 18 } 19 bool
vis[110]; 20 int match[110]; 21 int Dfs(int u){ 22 for(int i=fir[u];i!=-1;i=ne[i]){ 23 int v=to[i]; 24 if(!vis[v]){ 25 vis[v]=true; 26 if(match[v]==-1||Dfs(match[v])){ 27 match[v]=u; 28 return true; 29 }
30 } 31 } 32 return false; 33 } 34 int Hungary(){ 35 memset(match,-1,sizeof(match)); 36 int ret=0; 37 for(int i=1;i<=N;i++){ 38 if(A[i]&&B[i]) continue; 39 memset(vis,false,sizeof(vis)); 40 if(Dfs(i)) ret++; 41 } 42 return ret; 43 } 44 int main(){ 45 int Test=readint(); 46 while(Test--){ 47 memset(fir,-1,sizeof(fir)); 48 cnt=0; 49 N=readint(); 50 for(int i=1;i<=N;i++) A[i]=readint(); 51 for(int i=1;i<=N;i++) B[i]=readint(); 52 for(int i=1;i<=N;i++) 53 for(int j=1;j<=N;j++){ 54 bool x=readint(); 55 if(!x||(!A[j])||(A[i]&&B[i])) continue; 56 Add(i,j+N); 57 } 58 for(int i=1;i<=N;i++) 59 if(A[i]&&(!B[i])) 60 Add(i,i+N); 61 int tot=N; 62 for(int i=1;i<=N;i++) 63 if(A[i]&&B[i]) 64 tot--; 65 int Ans=Hungary(); 66 if(Ans<tot) printf("%c%c%c\n",84,95,84); 67 else printf("%c%c%c\n",94,95,94); 68 } 69 return 0; 70 }

[BZOJ1433][ZJOI2009]假期的宿舍 二分圖匹配