POJ 3041 Asteroids 二分图之最大匹配

题意:在一个网格中有若干个点,每一次可以清除一行或者一列,问最少几次可以将网格中的点全部清除。

思路:这个题是一个入门的最大匹配题(这个好像不是思路..)。一般的方式就是将 行 看作集合A,列 看作集合B。

这么说有点抽象。举个例子:2行3列的矩阵可以看作是集合A={1,2}与B={1,2,3},假设矩阵[1][2] 存在点(别忘了题意),则A中的元素1与B中元素2连有一条边。

这样就可以将题给矩阵转化为二分图,再利用匈牙利算法得到最大匹配数就是答案了。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int n, k;
 5 int v1, v2;//二分图顶点集,都等于n
 6 bool map[501][501];
 7 bool visit[501]; //记录v2中的每个点是否被搜索过
 8 int link[501]; //记录v2中的点y在v1中所匹配的点x的编号
 9 int result;//最大匹配数
10 bool dfs(int x)
11 
12 {
13     for (int y = 1; y <= v2; y++)
14     {
15         if (map[x][y] && !visit[y])
16         {
17             visit[y] = true;
18             if (link[y] == 0 || dfs(link[y]))
19             {
20                 link[y] = x;
21                 return 1;
22             }
23         }
24     }
25     return 0;
26 }
27 
28 //匈牙利算法hungary algorithm
29 void search()
30 {
31     for (int x = 1; x <= v1; x++)
32     {
33 
34         memset(visit,false,sizeof(visit));
35 
36         if (dfs(x)) //从v1中的节点x开始寻找增广路径p
37 
38             result++;
39     }
40 }
41 
42 int main()
43 {
44     cin >> n >> k;
45     v1 = v2 = n;
46     int x, y;
47     memset(map,0,sizeof(map));
48     for (int i = 1; i <= k; i++)
49     {
50         cin >> x >> y;
51         map[x][y] = true;
52     }
53     search();
54     cout << result << endl;
55     return 0;
56 }

 

posted @ 2018-07-31 21:29  llllrj  阅读(124)  评论(0编辑  收藏  举报