题目描述
小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏。矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的)。每次可以对该矩阵进行两种操作:
行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)
列交换操作:选择矩阵的任意两列,交换这两列(即交换对应格子的颜色)
游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。
对于某些关卡,小Q百思不得其解,以致他开始怀疑这些关卡是不是根本就是无解的!!于是小Q决定写一个程序来判断这些关卡是否有解。
输入输出格式
输入格式:第一行包含一个整数T,表示数据的组数。
接下来包含T组数据,每组数据第一行为一个整数N,表示方阵的大小;接下来N行为一个N*N的01矩阵(0表示白色,1表示黑色)。
输出格式:包含T行。对于每一组数据,如果该关卡有解,输出一行Yes;否则输出一行No。
输入输出样例
说明
对于20%的数据,N ≤ 7
对于50%的数据,N ≤ 50
对于100%的数据,N ≤ 200
二分图
如果a[i][j]是黑色,那么i,j建边
然后用匈牙利算FA
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n,match[201],T,ans; 7 bool vis[201],map[201][201]; 8 bool dfs(int x) 9 { 10 for (int i=1;i<=n;i++) 11 if (map[x][i]==true&&vis[i]==false) 12 { 13 vis[i]=true; 14 if (match[i]==0||dfs(match[i])) 15 { 16 match[i]=x; 17 return 1; 18 } 19 } 20 return 0; 21 } 22 int main() 23 {int l,i,j,x; 24 //freopen("6.in","r",stdin); 25 //freopen("6.out","w",stdout); 26 cin>>T; 27 for (l=1;l<=T;l++) 28 { 29 memset(map,false,sizeof(map)); 30 memset(match,0,sizeof(match)); 31 memset(vis,false,sizeof(vis)); 32 ans=0; 33 scanf("%d",&n); 34 for (i=1;i<=n;i++) 35 for (j=1;j<=n;j++) 36 { 37 scanf("%d",&x); 38 if (x==1) map[i][j]=true; 39 } 40 for (i=1;i<=n;i++) 41 { 42 memset(vis,false,sizeof(vis)); 43 if (!dfs(i)) break; 44 } 45 if (i>n) printf("Yes\n"); 46 else printf("No\n"); 47 } 48 }