POJ3041 Asteroids【二分匹配】

来源:互联网 发布:淘宝app怎么下载不了 编辑:程序博客网 时间:2024/06/05 16:37

题意:一张图上有许多障碍物,一发炮弹能摧毁一行或一列的障碍物,问最少需要几发


思路:把每行看成匹配的左列,把列看成匹配的右列,(i,j)这个点表示需要第i行或第j列的一发炮弹即可,认为它们有一条边。那么现在问题就变为最少需要几个点,这些点延伸出的边能覆盖所有点。最小点覆盖 = 最大匹配数


#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<stdlib.h>#include<math.h>#include<vector>#include<list>#include<map>#include<stack>#include<queue>#include<algorithm>#include<numeric>#include<functional>using namespace std;typedef long long ll;const int maxn = 505;int girl[maxn],vis[maxn],num[maxn][maxn],n,m;void init(int x){memset(girl,-1,sizeof girl);memset(num,0,sizeof num);}int fid(int x) // 为匹配x{for(int j = 1; j <= n; j++){if(!vis[j] && num[x][j]){vis[j] = 1;if(girl[j] == -1 || fid(girl[j]) ){girl[j] = x;return 1;}}}return 0;}int main(void){while(scanf("%d%d",&n,&m)!=EOF){init(n);for(int i = 1; i <= m; i++){int a,b;scanf("%d%d",&a,&b);num[a][b] = i;}int ans = 0;for(int i = 1; i <= n; i++){memset(vis,0,sizeof vis);if(fid(i))ans++;}printf("%d\n",ans);}return 0;}




原创粉丝点击