题目链接: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 ",84,95,84); 67 else printf("%c%c%c ",94,95,94); 68 } 69 return 0; 70 }