首页 > 代码库 > Vijos CoVH之柯南开锁 (二分图)

Vijos CoVH之柯南开锁 (二分图)

背景

随着时代的演进,困难的刑案也不断增加...
但真相只有一个
虽然变小了,头脑还是一样好,这就是名侦探柯南!

描述

[CoVH06]
面对OIBH组织的嚣张气焰, 柯南决定深入牛棚, 一探虚实.
他经过深思熟虑, 决定从OIBH组织大门进入...........

OIBH组织的大门有一个很神奇的锁.
锁是由M*N个格子组成, 其中某些格子凸起(灰色的格子). 每一次操作可以把某一行或某一列的格子给按下去.
技术分享
如果柯南能在组织限定的次数内将所有格子都按下去, 那么他就能够进入总部. 但是OIBH组织不是吃素的, 他们的限定次数恰是最少次数.

请您帮助柯南计算出开给定的锁所需的最少次数.

格式

输入格式

第一行 两个不超过100的正整数N, M表示矩阵的长和宽
以下N行 每行M个数 非0即1 1为凸起方格

输出格式

一个整数 所需最少次数

样例1

样例输入1

4 40000010100000100
Copy

样例输出1

2
Copy

限制

全部1秒

提示

OIBH组织的第一道防线居然被柯南突破了. 这引起了OIBH组织的高度重视, 他们派出了黄金十二人+青铜五小强进行抵抗.

 

 1 /* 2     一个很老的经典的二分图的梗了 3     看成两部分分别为(1..n)和(1..m)的二分图 4     若(x,y)=1 则给x-->y连条边 5     问题转化为选出最少的点使以这些点为端点的所有边的集合为所有边的集合 6     也就是最小点覆盖数了 7     根据K?nig定理我们可以知道 二分图的最大匹配等于这个图的最小点覆盖数 8     这个鬼东西自己记下来就好了 9 */10 #include<iostream>11 #include<cstring>12 #include<cstdio>13 #define MAXN 10214 15 using namespace std;16 17 int map[MAXN][MAXN],n,m,link[MAXN],ans;18 bool vis[MAXN];19 20 char x;21 22 inline bool find(int x) {23     for(int i=1;i<=m;i++) {24         if(!vis[i]&&map[x][i]) {25             vis[i]=true;26             if(link[i]==0||find(link[i])) {27                 link[i]=x;28                 return true;29             }30         }31     }32     return false;33 }34 35 int main() {36     scanf("%d%d",&n,&m);37     getchar();38     for(int i=1;i<=n;i++) {39         for(int j=1;j<=m;j++) {40             cin>>x;41             if(x==1) map[i][j]=1;42           }43           getchar();44     }45     for(int i=1;i<=n;i++) {46         memset(vis,0,sizeof vis);47         if(find(i)) ans++;48     }49     printf("%d\n",ans);50     return 0;51 }

 

Vijos CoVH之柯南开锁 (二分图)