P1129 [ZJOI2007]矩陣遊戲 二分匹配

  

題目描述

小QQ是一個很是聰明的孩子,除了國際象棋,他還很喜歡玩一個電腦益智遊戲――矩陣遊戲。矩陣遊戲在一個N \times NN×N黑白方陣進行(如同國際象棋通常,只是顏色是隨意的)。每次能夠對該矩陣進行兩種操做:c++

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

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

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

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

輸入輸出格式

輸入格式:it

 

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

接下來包含TT組數據,每組數據第一行爲一個整數NN,表示方陣的大小;接下來NN行爲一個N \times NN×N的0101矩陣(00表示白色,11表示黑色)。sed

 

輸出格式:程序

 

包含TT行。對於每一組數據,若是該關卡有解,輸出一行YesYes;不然輸出一行NoNo。方法

 

輸入輸出樣例

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

說明

對於20\%20%的數據,N ≤ 7N≤7

對於50\%50%的數據,N ≤ 50N≤50

對於100\%100%的數據,N ≤ 200N≤200

 

和以前那道棋盤(車)相似  

對行列進行二分

顯然  當徹底匹配的時候   也就是匹配數==n

確定有方法轉換

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=1000+5;
const int M=100*N;
int head[M],pos,n;
struct Edge
{
    int nex,to;
}edge[M];
void add(int a,int b)
{
    edge[++pos].nex=head[a];
    head[a]=pos;
    edge[pos].to=b;
}
int vis[N],used[N];

bool dfs(int x)
{
    for(int i=head[x];i;i=edge[i].nex)
    {
        int v=edge[i].to;
        if(!used[v])
        {
            used[v]=1;
            if(!vis[v]||dfs(vis[v]))
            {
                vis[v]=x;
                return true;
            }
        }
    }
    return false;
}

int find1()
{
    CLR(vis,0);
    int ans=0;
    rep(i,1,n)
    {
        CLR(used,0);
        if(dfs(i))ans++;
    }
  //printf("ans=%d\n",ans);
    return ans==n;
}
void init()
{
    pos=0;
    CLR(head,0);
}
int main()
{
    int cas;RI(cas);
    while(cas--)
    {
        RI(n);
        init();
        rep(i,1,n)
        rep(j,1,n)
        {
            int x;RI(x);
            if(x)add(i,j);
        }
        if(find1())
            printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
View Code
相關文章
相關標籤/搜索