[bzoj1059]矩陣遊戲

1059: [ZJOI2007]矩陣遊戲

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4731  Solved: 2255
[Submit][Status][Discuss]

Description

  小Q是一個非常聰明的孩子,除了國際象棋,他還很喜歡玩一個電腦益智遊戲——矩陣遊戲。矩陣遊戲在一個N*N黑白方陣進行(如同國際象棋一般,只是顏色是隨意的)。每次可以對該矩陣進行兩種操作:行交換操作:選擇
矩陣的任意兩行,交換這兩行(即交換對應格子的顏色)列交換操作:選擇矩陣的任意行列,交換這兩列(即交換
對應格子的顏色)遊戲的目標,即通過若干次操作,使得方陣的主對角線(左上角到右下角的連線)上的格子均爲黑
色。對於某些關卡,小Q百思不得其解,以致他開始懷疑這些關卡是不是根本就是無解的!!於是小Q決定寫一個程
序來判斷這些關卡是否有解。

Input

  第一行包含一個整數T,表示數據的組數。接下來包含T組數據,每組數據第一行爲一個整數N,表示方陣的大
小;接下來N行爲一個N*N的01矩陣(0表示白色,1表示黑色)。

Output

  輸出文件應包含T行。對於每一組數據,如果該關卡有解,輸出一行Yes;否則輸出一行No。

Sample Input

2
2
0 0
0 1
3
0 0 1
0 1 0
1 0 0

Sample Output

No
Yes
【數據規模】
對於100%的數據,N ≤ 200

HINT

Source

題解

難點就在於不好想到二分圖匹配
對於同行的兩個點 怎麼變都是同行 對於同列的一樣
但是對角線的每個點 行列都不同 所以求能不能找到n個互相不同行而且不同列的點。
也就是說每個行只能對應一個列 每個列只能對應一個行 求二分圖最大匹配即可 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int flag[250],mat[250],mp[205][250],n;
bool km(int x){
	for(int i=1;i<=n;i++)
	{
		if(mp[x][i]&&!flag[i]){
			flag[i]=1;
			if(!mat[i]||km(mat[i]))
			{
				mat[i]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
        memset(mat,0,sizeof(mat));
		scanf("%d",&n);
		int x;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{	scanf("%d",&x);
				if(x) mp[i][j]=1;
				else mp[i][j]=0;
			}
		int ans=0;
		for(int i=1;i<=n;i++){
			memset(flag,0,sizeof(flag));
			if(km(i))ans++;
		}
		if(ans==n) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章