[ZJOI2007]矩阵游戏【bzoj1059/洛谷1129】


QQ是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏。矩阵游戏在一个N \times NN×N黑白方阵进行(如同国际象棋一般,只是颜色是随意的)。每次可以对该矩阵进行两种操作:

行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)

列交换操作:选择矩阵的任意两列,交换这两列(即交换对应格子的颜色)

游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。

对于某些关卡,小QQ百思不得其解,以致他开始怀疑这些关卡是不是根本就是无解的!于是小QQ决定写一个程序来判断这些关卡是否有解。

         

       目标状态要求矩阵的主对角线上的格子均为黑色。

        即是(1,1),(2,2),(3,3)......(n,n)皆匹配;

        如果原图满足每行和每列都匹配,那么通过交换,一定可以换成上面这种情况。

         所以拆行和列跑一个最大二分图匹配,并判断匹配数是否等于n即可。

         代码见

       

#include<bits/stdc++.h>
#define re register int
#define maxn 200+5
using namespace std;
int t,n;
int ma[maxn][maxn];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*f;
}
int ans,match[maxn];
bool ed[maxn][maxn],vis[maxn];
bool dfs(int x){
for(re i=1;i<=n;i++)
if(!vis[i]&&ed[x][i]){
vis[i]=true;
if(!match[i]||dfs(match[i]))
{
match[i]=x;
return true;
}
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
t=read();
while(t--)
{
ans=0;
memset(match,0,sizeof(match));
memset(ed,false,sizeof(ed));
n=read();
for(re i=1;i<=n;i++)
for(re j=1;j<=n;j++)
ed[i][j]=read();
for(re i=1;i<=n;i++)
{
memset(vis,false,sizeof(vis));
ans+=dfs(i);
}
if(ans==n) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
} 
return 0;

}
View Code

猜你喜欢

转载自www.cnblogs.com/3200Pheathon/p/10704041.html
今日推荐