Asteroids POJ

Asteroids POJ - 3041

  题目大意:N*N的地图里,存在一些小行星,Bessie有个很牛x但又很耗蓝的武器,一次可以消灭一行或者一列的所有小行星,问最少使用多少次这个武器可以消灭所有的小行星?

  第一次做这种建图的题,把每一行和每一列都视为一个点,然后给出的小行星坐标x,y就视为在x点和y点间连一条边,那么就是求最小点覆盖,而最小点覆盖=最大匹配(具体概念和证明之后再填坑),所以直接跑一遍匈牙利算法

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<set>
 4 using namespace std;
 5 set<int> x[520];//因为可能有重复的边,所以我用set 
 6 int vis[520],y[520];
 7 int match(int u)
 8 {
 9     for(set<int>::iterator it=x[u].begin();it!=x[u].end();it++)
10     {
11         int v=*it;
12         if(!vis[v])
13         {
14             vis[v]=1;
15             if(!y[v]||match(y[v]))
16             {
17                 y[v]=u;
18                 return 1;
19             }
20         }
21     }
22     return 0;
23 }
24 int main()
25 {
26     int n,k,a,b;
27     while(~scanf("%d%d",&n,&k))
28     {
29         for(int i=0;i<=n;i++)
30             x[i].clear();
31         while(k--)
32         {
33             scanf("%d%d",&a,&b);
34             x[a].insert(b);//对应的行和列连边 
35         }
36         int ans=0;
37         memset(y,0,sizeof(y));
38         for(int i=1;i<=n;i++)//求行列的最大匹配 
39         {
40             memset(vis,0,sizeof(vis));
41             ans+=match(i);
42         }
43         printf("%d
",ans);
44     }
45     return 0;
46 }
点点边边变换无穷
原文地址:https://www.cnblogs.com/LMCC1108/p/10642770.html