poj 3041 Asteroids (最小点覆盖)

链接:poj 3041

题意:有一个n*n的矩阵,在矩阵上有m个行星,一个武器可以消灭同一行或者同一列的星星

求最小的要用多少武器消灭所有的星星

思路:把方阵看做一个特殊的二分图(以行列分别作为两个顶点集V1、V2,其中|V1|=|V2|)

然后把每行x或者每列y看成一个点,而障碍物(x,y)可以看做连接x和y的边。按照这种思路建图,问题就转化成为选择最少的一些点(x或y),使得从这些点与所有的边相邻,其实这就是最小点覆盖问题。

最小点覆盖数 = 最大匹配数

这样本题就转化为求最大匹配数了

  1. #include<stdio.h>  
  2. #include<string.h>  
  3. int edge[550][550],n,used[550],link[550];  
  4. int dfs(int pos)  
  5. {  
  6.     int i;  
  7.     for(i=1;i<=n;i++)  
  8.         if(edge[pos][i]&&!used[i]){  
  9.             used[i]=1;  
  10.             if(link[i]==-1||dfs(link[i])){  
  11.                 link[i]=pos;  
  12.                 return 1;  
  13.             }  
  14.         }  
  15.     return 0;  
  16. }  
  17. int main()  
  18. {  
  19.     int i,a,b,s,m;  
  20.     scanf("%d%d",&n,&m);  
  21.     memset(edge,0,sizeof(edge));  
  22.     for(i=0;i<m;i++){  
  23.         scanf("%d%d",&a,&b);  
  24.         edge[a][b]=1;  
  25.     }  
  26.     s=0;  
  27.     memset(link,-1,sizeof(link));  
  28.     for(i=1;i<=n;i++){  
  29.         memset(used,0,sizeof(used));  
  30.         s+=dfs(i);  
  31.     }  
  32.     printf("%d\n",s);  
  33.     return 0;  
  34. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值