1. 程式人生 > >洛谷 P1129 BZOJ 1059 cogs 660 [ZJOI2007]矩陣遊戲

洛谷 P1129 BZOJ 1059 cogs 660 [ZJOI2007]矩陣遊戲

nbsp sca set 思路 右下角 pan out 最大匹配 matrix

題目描述

小Q是一個非常聰明的孩子,除了國際象棋,他還很喜歡玩一個電腦益智遊戲――矩陣遊戲。矩陣遊戲在一個N*N黑白方陣進行(如同國際象棋一般,只是顏色是隨意的)。每次可以對該矩陣進行兩種操作:

行交換操作:選擇矩陣的任意兩行,交換這兩行(即交換對應格子的顏色)

列交換操作:選擇矩陣的任意兩列,交換這兩列(即交換對應格子的顏色)

遊戲的目標,即通過若幹次操作,使得方陣的主對角線(左上角到右下角的連線)上的格子均為黑色。

對於某些關卡,小Q百思不得其解,以致他開始懷疑這些關卡是不是根本就是無解的!!於是小Q決定寫一個程序來判斷這些關卡是否有解。

輸入輸出格式

輸入格式:

第一行包含一個整數T,表示數據的組數。

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

輸出格式:

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

輸入輸出樣例

輸入樣例#1:
2
2
0 0
0 1
3
0 0 1
0 1 0
1 0 0
輸出樣例#1:
No
Yes

說明

對於20%的數據,N ≤ 7

對於50%的數據,N ≤ 50

對於100%的數據,N ≤ 200

解題思路

  把給的矩陣當鄰接矩陣跑二分圖最大匹配,如果存在完美匹配(匹配數等於n),則輸出Yes,否則輸出No(最近狀態不太好,感覺這解釋好敷衍啊……過幾天填坑)

源代碼

#include<cstdio>
#include<cstring>
#define QL(x) memset(x,0,sizeof(x))
int map[240][240]={0};
int woman[240]={0},vis[240]={0};
int t,n;
bool dfs(int u)
{
    for(int v=1;v<=n;v++)
    {
        if(!map[u][v]) continue;
        if(vis[v]) continue;
        vis[v]=1;
        
if(!woman[v]||dfs(woman[v])) {woman[v]=u;return 1;} } return 0; } int main() { //freopen("qmatrix.in","r",stdin); //freopen("qmatrix.out","w",stdout);//cogs scanf("%d",&t); while(t--) { QL(woman),QL(map); scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1,k;j<=n;j++) { scanf("%d",&map[i][j]); } }int i=1; for(;i<=n;i++) { QL(vis); if(!dfs(i)) {printf("No\n");break;} } if(i>n) printf("Yes\n"); } return 0; }

洛谷 P1129 BZOJ 1059 cogs 660 [ZJOI2007]矩陣遊戲