码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI2007]矩阵游戏

时间:2017-12-28 23:31:03      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:条件   解题思路   line   read   匹配   交换   class   cpp   str   

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

 

[ZJOI2007]矩阵游戏

标签:条件   解题思路   line   read   匹配   交换   class   cpp   str   

原文地址:https://www.cnblogs.com/Mrsrz/p/8137843.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!