[ZJOI2007]矩阵游戏

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

 

posted @ 2017-12-28 21:28  Mrsrz  阅读(251)  评论(0编辑  收藏  举报