poj 3041 Asteroids

来源:互联网 发布:广州软件开发公司 编辑:程序博客网 时间:2024/05/22 06:20

题意: 在一个n*n的网格中分布了K个危险的小行星,Bessie有一种强大的武器,一枚子弹可以消灭一行或一列的小行星,问最少要发射多少颗子弹,消灭所有的小行星。


分析:将每个顶点的x坐标和y坐标分别看成两个集合的结点,然后建立二分图;这样要发射最少的子弹消灭所有的小行星就是选最少的点覆盖所有的边,即点覆盖数。

点覆盖数 = 匹配数,那么二分图的匹配数即为所求。


以下附上代码:

#include <algorithm>#include <iostream>#include <sstream>#include <fstream>#include <cstring>#include <cstdio>#include <vector>#include <cctype>#include <cmath>#include <stack>#include <queue>#include <list>#include <map>#include <set>using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 505;int n,m;int edge[maxn][maxn];int cx[maxn],cy[maxn];int vis[maxn];void input(){  int u,v;  int i,j;  for(i = 0; i <= n; i++){    for(j = 0; j <=n; j++){      edge[i][j] = 0;    }  }    for(i = 0; i < m; i++){    scanf("%d%d",&u,&v);    edge[u][v] = 1;  }  }int findPath(int u){  for(int v = 1; v <= n; v++) {    if(!vis[v] && edge[u][v]){      vis[v] = 1;      if(cy[v] == -1 || findPath(cy[v])){        cx[u] = v;        cy[v] = u;        return 1;      }    }  }  return 0;}int maxMatch(){  int res = 0;  fill(cx,cx+n+1,-1);  fill(cy,cy+n+1,-1);  for(int i = 1; i <= n; i++){    if(cx[i] == -1){      fill(vis,vis+n+1,0);      res += findPath(i);    }  }  return res;}void solve(){  printf("%d\n",maxMatch()) ;}int main(){  while(scanf("%d%d",&n,&m) != EOF){    input();    solve();  }return 0;}


0 0
原创粉丝点击