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

[ZJOI2007]矩阵游戏-二分图匹配

时间:2018-11-08 18:34:18      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:==   space   hung   ++   clu   sed   二分   alt   close   

这个题我们可以从终态入手,

我们发现题目要求的是能否成为使得对角线上都是黑棋。

它具有什么特征呢?那就是保证了每一行每一列存在一个黑点。

那么我们只要能够保证这张图上,至少存在n个点恰好能够覆盖n行n列,那么就一定可以转换成终态。

所以呢怎么判断给定的图是不是满足这个条件呢?

我们把行列分开看,每一个黑棋s[i,j],就对应着第i行和第j列有一条连边。

我们发现,这就相当于一个二分图,而我们只需判断一下这二分图是否存在>=n的匹配就好了。

技术分享图片
#include <bits/stdc++.h>
using namespace std;
inline int gi () {
    int x=0, w=0; char ch=0;
    while (!(ch>=0&&ch<=9)) {
        if (ch==-) w=1;
        ch=getchar();
    }
    while (ch>=0&&ch<=9) {
        x=(x<<3)+(x<<1)+(ch^48);
        ch=getchar();
    }
    return w?-x:x;
}

int T,n,ans,a[210][210],Vis[210],Guys[210];

bool Hungry (int x) {
    for (int i=1;i<=n;++i) {
        if (Vis[i]||!a[x][i]) continue;
        Vis[i]=1;
        if (!Guys[i]||Hungry(Guys[i])) {
            Guys[i]=x;
            return 1;
        }
    }
    return 0;
}

int main ()
{
    T=gi ();
    while (T--) {
        n=gi ();
        ans=0;
        memset (a,0,sizeof(a));
        memset (Guys,0,sizeof(Guys)); 
        for (int i=1;i<=n;++i)
            for (int j=1;j<=n;++j)
                a[i][j]=gi ();
        for (int i=1;i<=n;++i) {
            memset (Vis,0,sizeof(Vis));
        if (Hungry(i)) ++ans; 
        }
        ans>=n?puts("Yes"):puts("No");
    }
    return 0;
}
BY BHLLX

 

[ZJOI2007]矩阵游戏-二分图匹配

标签:==   space   hung   ++   clu   sed   二分   alt   close   

原文地址:https://www.cnblogs.com/Bhllx/p/9929882.html

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