AmazingCounters.com

BZOJ1059: [ZJOI2007]矩阵游戏

题目在这儿:http://www.lydsy.com/JudgeOnline/problem.php?id=1059

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
【数据规模】
对于20%的数据,N ≤ 7
对于50%的数据,N ≤ 50
对于100%的数据,N ≤ 200
或者点这里看题

做法:由于每一行每一列只要有一个黑点确定了,那么这一行这一列就不能动了,于是可以二分图匹配:把行和列有交点的连一条边,求最大匹配数是否等于n。需要注意的是,建边的时候。。要注意 x->y+n(显然,邻接矩阵的勿喷。。)

Codes:

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;
 8 const int N = 210;
 9 #define For(i,n) for(int i=1;i<=n;i++)
10 #define Rep(i,l,r) for(int i=l;i<=r;i++)
11 
12 struct EDGE{
13     int t,next;
14 }E[N*N];
15 bool vis[2*N];
16 int head[2*N],cnt;
17 int T,n,Link[2*N],w;
18 
19 void makelist(int s,int t){
20     E[cnt].t = t; E[cnt].next = head[s];
21     head[s] = cnt++;
22 }
23 
24 bool find(int u){
25     int p = head[u];
26     while(p!=-1){
27             if(!vis[E[p].t]){
28             vis[E[p].t] = true;
29             if(!Link[E[p].t]||find(Link[E[p].t])){
30                 Link[E[p].t] = u;
31                 return true;
32             }
33         }
34         p = E[p].next;
35     }
36     return false;
37 }
38 
39 void solve(){
40     For(i,n){
41         memset(vis,false,sizeof(vis));
42         if(!find(i)){
43             puts("No");
44             return;
45         }
46     }
47     puts("Yes");
48 }
49 
50 int main(){
51     scanf("%d",&T);
52     For(i,T){
53         scanf("%d",&n);
54         memset(head,-1,sizeof(head));cnt = 0;
55         memset(Link,0,sizeof(Link));
56         For(x,n)
57           For(y,n) {
58               scanf("%d",&w);
59               if(w)  makelist(x,y+n);
60           }
61         solve();
62     }
63     return 0;
64 }
View Code

 

 

 

posted @ 2014-05-26 20:06  ZJDx1998  阅读(131)  评论(0编辑  收藏  举报