首页 > 其他 > 详细

BZOJ 1059 [ZJOI2007]矩阵游戏:二分图匹配

时间:2018-02-08 19:25:42      阅读:284      评论:0      收藏:0      [点我收藏+]

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1059

题意:

  给你一个n*n的01矩阵。

  你可以任意次地交换某两行或某两列。

  问你是否可以让这个矩阵的主对角线(左上角到右下角的连线)上的格子均为黑色。

 

题解:

  可以发现,对于一个格子,无论怎样移动,它原来行(列)上的格子还是在现在的行(列)上。

  因为最终目标是将n个黑色格子移到对角线上,所以只要有n个黑色格子的行列均不相同即可。

  那么对于每个黑色格子,将行号i向列号j连一条边,然后跑二分图匹配,看匹配数是否等于n即可。

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <vector>
 5 #define MAX_N 205
 6 
 7 using namespace std;
 8 
 9 int n,t;
10 int vis[MAX_N];
11 int match[MAX_N];
12 vector<int> edge[MAX_N];
13 
14 void read()
15 {
16     cin>>n;
17     for(int i=1;i<=n;i++) edge[i].clear();
18     int x;
19     for(int i=1;i<=n;i++)
20     {
21         for(int j=1;j<=n;j++)
22         {
23             cin>>x;
24             if(x) edge[i].push_back(j);
25         }
26     }
27 }
28 
29 bool hungary(int now,int cnt)
30 {
31     for(int i=0;i<edge[now].size();i++)
32     {
33         int temp=edge[now][i];
34         if(vis[temp]!=cnt)
35         {
36             vis[temp]=cnt;
37             if(match[temp]==-1 || hungary(match[temp],cnt))
38             {
39                 match[temp]=now;
40                 return true;
41             }
42         }
43     }
44     return false;
45 }
46 
47 void work()
48 {
49     memset(vis,0,sizeof(vis));
50     memset(match,-1,sizeof(match));
51     for(int i=1;i<=n;i++)
52     {
53         if(!hungary(i,i))
54         {
55             cout<<"No"<<endl;
56             return;
57         }
58     }
59     cout<<"Yes"<<endl;
60 }
61 
62 int main()
63 {
64     cin>>t;
65     while(t--)
66     {
67         read();
68         work();
69     }
70 }

 

BZOJ 1059 [ZJOI2007]矩阵游戏:二分图匹配

原文:https://www.cnblogs.com/Leohh/p/8432615.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!