[题解]luogu_P1129_矩阵游戏(二分图

补原来的题解

重要性质:发现两个黑块一开始不在一行/列不管怎么交换都不能到一行/列,

格子图考虑二分图的话,每个黑点做边连接行和列,想要对角线都有黑点意思就是每个行和列都有黑点连接,最大匹配等于n即可

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=209;
int T,n,a[maxn][maxn],tim,ans;
struct node{
    int v,nxt;
}e[maxn*maxn];
int head[maxn*maxn],cnt;
inline void add(int u,int v){
    e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;
}
int v[maxn*2],b[maxn*2];
bool dfs(int x){
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].v;
        if(v[y]!=tim){
            v[y]=tim;
            if(!b[y]||dfs(b[y])){
                b[y]=x;return 1;
            }
        }
    }
    return 0;
}

int main(){
    scanf("%d",&T);
    while(T--){
        ans=0;cnt=0;
        memset(e,0,sizeof(e));
        memset(head,0,sizeof(head));
        memset(b,0,sizeof(b));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            scanf("%d",&a[i][j]);
            if(a[i][j])add(i,j+n);
        }
        for(int i=1;i<=n;i++){
            tim++;
            if(dfs(i))ans++;
        }
        if(ans>=n)printf("Yes\n");
        else printf("No\n");
    }
}

 

posted @ 2019-09-11 16:19  羊肉汤泡煎饼  阅读(136)  评论(0编辑  收藏  举报