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 }

 

posted @ 2016-08-12 20:45  PosProteus  阅读(134)  评论(0编辑  收藏  举报