题目:洛谷P1129、BZOJ1059。
题目大意:有正方形棋盘,每个点都是白色或黑色。现在可以任意交换某两行或两列的所有格子,问是否可能使主对角线的所有格子都为黑色?
解题思路:经过观察和思考,我们可以发现,要使条件达成,必须每行每列都存在黑格子。
如果某一行(列)没有,则必定存在一行(列)全是白色,则条件无法达成。
反之,一定可以通过一系列移动,从而满足条件。
所以转化为二分图匹配,若匹配数与行数相等,则可行,否则不可行。
匈牙利即可。
C++ Code:
#include<cstdio>
#include<cctype>
#include<cstring>
int n,lf[202];
bool b[202][202],vis[202];
inline int readint(){
char c=getchar();
for(;!isdigit(c);c=getchar());
int d=0;
for(;isdigit(c);c=getchar())
d=(d<<3)+(d<<1)+(c^'0');
return d;
}
bool dfs(int u){
for(int v=1;v<=n;++v)
if(!vis[v]&&b[u][v]){
vis[v]=true;
if(!lf[v]||dfs(lf[v])){
lf[v]=u;
return true;
}
}
return false;
}
int main(){
for(int T=readint();T--;){
n=readint();
memset(b,0,sizeof b);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
b[i][j]=(bool)readint();
bool ok=true;
memset(lf,0,sizeof lf);
for(int i=1;i<=n;++i){
memset(vis,0,sizeof vis);
if(!(ok=dfs(i)))break;
}
puts(ok?"Yes":"No");
}
return 0;
}