题目:洛谷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; }