版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/82262038
题目
一个
黑白方阵,每次可以对该矩阵进行两种操作:
行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)
列交换操作:选择矩阵的任意两列,交换这两列(即交换对应格子的颜色)
游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。
问是否有解
分析
可以发现无论怎么交换,二分图匹配的答案是不变的,所以说跑一遍匈牙利算法,如果每行每列都能匹配,那么即为有解
代码
#include <cstdio>
#include <cstring>
bool a[501][501],v[501]; int n,link[501];
int in(){
int ans=0; char c=getchar();
while (c<48||c>57) c=getchar();
while (c>47&&c<58) ans=ans*10+c-48,c=getchar();
return ans;
}
bool dfs(int x){//匈牙利算法
for (register int i=1;i<=n;i++)
if (a[x][i]&&!v[i]){
v[i]=1; int q=link[i];
link[i]=x;//记录路径
if (!q||dfs(q)) return 1;
link[i]=q;
}
return 0;
}
int main(){
int t=in();
while (t--){
n=in(); int ans=0;
memset(link,0,sizeof(link));
for (register int i=1;i<=n;i++)
for (register int j=1;j<=n;j++) a[i][j]=in();
for (register int i=1;i<=n;i++)
memset(v,0,sizeof(v)),ans+=dfs(i);
if (ans==n) printf("Yes\n"); else printf("No\n");
}
return 0;
}