poj 3041 Asteroids (二分图的最大匹配 第一题)

题目:http://poj.org/problem?id=3041

题意:在某个n*n的空间内,分布有一些小行星,某人在里面打炮,放一枪后某一行或某一列的行星就都没了,让求最少的打炮数。

然后把每行x或者每列y看成一个点,而障碍物(x,y)可以看做连接x和y的边。按照这种思路构图后。

问题就转化成为选择最少的一些点(x或y),使得从这些点与所有的边相邻,其实这就是最小点覆盖问题。

再利用二分图最大匹配的König定理:最小点覆盖数 = 最大匹配数

现在还是很多地方不会

最小点覆盖:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖图的所有的边。

 1 #include <iostream>
 2  #include<cstdio>
 3  #include<cstring>
 4  #include<cstdlib>
 5  #include<stack>
 6  #include<queue>
 7  #include<iomanip>
 8  #include<cmath>
 9  #include<algorithm>
10  using namespace std;
11  
12  int vis[1000],G[510][510],link[1000];
13  int n;
14  int find(int x)
15  {
16      int i;
17      for(i=1; i<=n; i++)
18      {
19          if(G[x][i]&&!vis[i])
20          {
21              vis[i]=1;
22              if(link[i]==0||find(link[i]))
23              {
24                  link[i]=x;
25                  return 1;
26              }
27          }
28      }
29      return 0;
30  }
31  int main()
32  {
33      int k,i,j,x,y,sum;
34      memset(link,0,sizeof(link));
35      memset(G,0,sizeof(G));
36      cin>>n>>k;
37      sum=0;
38      for(i=0; i<k; i++)
39      {
40          cin>>x>>y;
41          G[x][y]=1;
42      }
43      for(i=1; i<=n; i++)
44      {
45          memset(vis,0,sizeof(vis));
46          if(find(i))
47          sum++;
48      }
49      cout<<sum<<endl;
50      return 0;
51  }
52  

参考博客:http://www.cnblogs.com/pony1993/archive/2012/07/25/2607738.html

http://www.cnblogs.com/kuangbin/archive/2012/08/26/2657446.html

http://www.cnblogs.com/E-star/archive/2012/02/16/2354303.html

原文地址:https://www.cnblogs.com/bfshm/p/3262651.html