这个题我们可以从终态入手,
我们发现题目要求的是能否成为使得对角线上都是黑棋。
它具有什么特征呢?那就是保证了每一行每一列存在一个黑点。
那么我们只要能够保证这张图上,至少存在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
原文地址:https://www.cnblogs.com/Bhllx/p/9929882.html
时间: 2024-11-09 20:42:20