1. 程式人生 > >[ZJOI2007]矩陣遊戲

[ZJOI2007]矩陣遊戲

inline col class break 二分圖 ems 二分圖匹配 body pre

題目:洛谷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]矩陣遊戲