码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI2007]矩阵游戏(匈牙利)

时间:2019-07-11 20:29:20      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:str   连线   def   struct   clu   ash   while   +=   art   

题干:

  小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏。矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的)。每次可以对该矩阵进行两种操作:
  行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)
  列交换操作:选择矩阵的任意行列,交换这两列(即交换对应格子的颜色)
  游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。对于某些关卡,小Q百思不得其解,以致他开始怀疑这些关卡是不是根本就是无解的!于是小Q决定写一个程序来判断这些关卡是否有解。  

题解:

  其实这道题我们手模几个满足题干的状态就可知:每一纵列与每一横行的交点(1)一定是独一无二的。

0  0  0  1      0  1  0  0

1  0  0  0      1  0  0  0

0  0  1  0      0  0  0  1

0  1  0  0      0  0  1  0

  (上表其余位置均可填1)

  比较容易(太难了!!)就可以想到:每个黑点所对应的横纵坐标(x,y)所对应的就是一个二分图

  我们观察这两个表:每个点的横竖都没有黑点(1),或者说,其余的黑点对最终结果不造成任何影响(包括好的或坏的)

  当横纵坐标的值存在一一匹配的情况,就一定有解。

  那就用匈牙利算法来解决好了。(都快忘了。。。)

Code:

技术图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #define $ 222
 6 using namespace std;
 7 int b[$][$],m,n,ans,t,sum,first[$],tot,start[$];
 8 bool judge[$];
 9 struct tree{    int to,next;    }a[$*$];
10 inline void add(int x,int y){
11     a[++tot]=(tree){    y,first[x]    };
12     first[x]=tot;
13     /*a[++tot]=(tree){    x,first[y]    };
14     first[y]=tot;*/
15 }
16 inline bool km(int x){
17     for(register int i=first[x];i;i=a[i].next){
18         int to=a[i].to;
19         if(judge[to]) continue;
20         judge[to]=1;
21         if(!start[to]||km(start[to])){    start[to]=x; return 1;    }
22     }
23     return 0;
24 }
25 inline void work(){
26     memset(a,0,sizeof(a)); ans=tot=0;
27     memset(b,0,sizeof(b)); 
28     memset(judge,0,sizeof(judge));
29     memset(start,0,sizeof(start));
30     memset(first,0,sizeof(first));
31     scanf("%d",&n);
32     for(register int i=1;i<=n;++i) 
33         for(register int j=1;j<=n;++j){
34             scanf("%d",&b[i][j]);
35             b[i][j]?add(i,j),sum+=b[i][j]:1;
36         }
37     if(sum<n){    puts("No"); return;    }
38     for(register int i=1;i<=n;++i){
39         memset(judge,0,sizeof(judge));
40         if(km(i)) ++ans;
41     }
42     ans==n?puts("Yes"):puts("No");
43 }
44 signed main(){
45     scanf("%d",&t);
46     while(t--) work();
47 }
View Code

 

[ZJOI2007]矩阵游戏(匈牙利)

标签:str   连线   def   struct   clu   ash   while   +=   art   

原文地址:https://www.cnblogs.com/OI-zzyy/p/11172178.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!