Asteroids POJ - 3041
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\n",ans); 44 } 45 return 0; 46 }
我太难了~给个三连吧,亲~~~