【题解】 [ZJOI2007]矩阵游戏 (二分图匹配)

原题目戳我

 

Solution:

这个二分图藏还是挺深的,重点在哪里呢?首先我们分析下,交换影响的会是哪里。

每一次交换只会影响某一行上的排列或者某一列上的排列,如果有矩阵是下面这样,就一定不会互相影响。

1 0 0 0 0   |   0 0 1 0

0 0 1 0 0   |   1 0 0 0

0 1 0 0 0   |   0 0 0 1

0 0 0 0 1   |   0 1 0 0

0 0 0 1 0   |

所以我们就只用找每一行每一列能不能匹配出一个完美的二分图,若不能就输出No

 

Code:

 1 //It is coded by Ning_Mew on 3.15
 2 #include<bits/stdc++.h>
 3 
 4 const int maxn=200+7;
 5 
 6 int T,n,be[maxn];
 7 bool vis[maxn];
 8 int head[maxn],cnt=0;
 9 struct Edge{int nxt,to;}edge[maxn*maxn];
10 
11 void add(int from,int to){
12   edge[++cnt].nxt=head[from];
13   edge[cnt].to=to;
14   head[from]=cnt;
15 }
16 
17 void clear(){
18   memset(head,0,sizeof(head));cnt=0;
19   memset(be,-1,sizeof(be));
20 }
21 bool find(int k){
22   for(int i=head[k];i!=0;i=edge[i].nxt){
23     int v=edge[i].to;
24     if(!vis[v]){
25       vis[v]=true;
26       if(be[v]==-1||find(be[v])){be[v]=k;return true;}
27     }
28   }
29   return false;
30 }
31 void work(){
32   clear();
33   scanf("%d",&n);
34   for(int i=1;i<=n;i++){
35     for(int j=1;j<=n;j++){
36       int box;scanf("%d",&box);
37       if(box){add(j,i);}
38     }
39   }
40   for(int i=1;i<=n;i++){
41     memset(vis,false,sizeof(vis));
42     if(find(i));
43     else {printf("No\n");return;}
44   }
45   printf("Yes\n");return;
46 }
47 int main(){
48   scanf("%d",&T);
49   for(int i=1;i<=T;i++){work();}
50   return 0;
51 }
View Code

 

posted @ 2018-03-15 20:30  Ning_Mew  阅读(146)  评论(0编辑  收藏  举报