poj 3041 二分图最大匹配

题意:给定一个NxN的网格,其中有k个格点上有障碍物,每次可以消除一行或一列障碍物,问最少几次可以消除全部的障碍物。

思路:二分图的经典模型,将所有的行看作二分图中左边的端点,将所有的列看作右边的端点,当格点上有障碍物时,连一条边,问题转变为求二分图的最小顶点覆盖,根据König定理(二分图的最大匹配等于二分图的最小顶点覆盖)求最大匹配数即可

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #include<sstream>
 8 #include<iomanip>
 9 #include<vector>
10 #include<map>
11 #include<set>
12 #include<queue>
13 using namespace std;
14 const int MOD = 1e9 + 7;
15 
16 typedef long long LL;
17 typedef unsigned long long ULL;
18 
19 const int maxn = 505;
20 bool g[maxn][maxn];
21 int link[maxn];
22 bool check[maxn];
23 
24 int n;
25 
26 bool dfs(int u){
27     for(int i = 1; i <= n; ++i){
28          if(!check[i] && g[u][i]){
29              check[i] = true;
30              if(link[i] == -1 || dfs(link[i])){
31                   link[i] = u;
32                   return true;
33              }
34          }
35     }
36     return false;
37 }
38 
39 int hungarian(){
40     int ans = 0;
41     memset(link,-1,sizeof(link));
42     for(int i = 1; i <= n; ++i){
43         memset(check,0,sizeof(check));
44         if(dfs(i)) ++ans;
45     }
46     return ans;
47 }
48 
49 int main(){
50     int k;
51     scanf("%d%d",&n,&k);
52     int x,y;
53     for(int i = 0; i < k; ++i){
54          scanf("%d%d",&x,&y);
55          g[x][y] = 1;
56     }
57     printf("%d\n",hungarian());
58     return 0;
59 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值