您的位置:首页 > 其它

POJ 3041 Asteroids 二分匹配

2012-07-12 20:42 399 查看
/*题意:输入n,m,n代表一个n*n的图,m代表该图中有多少需要消灭的星球
输入m行数据,每行是一个星球的坐标。
找出要消灭所有星球所需要发射最少的次数。
一次发射可以毁灭一行或者一列的星球。
思路:
每个需要消灭的星球有一个坐标,分别是x,y,只需要发射x行或者y列都可消灭该星球。
所以可以根据x,y来建立二分图,求该图的最小点覆盖。
如样例:
1 1
1 3
2 2
3 2

1-1-3
2-2
3-2
所以最大匹配为2.
二分图中最小点覆盖=最大匹配。

*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2005
#define inf 1<<28
using namespace std;

int n;
bool visit[Max];
int match[Max];
vector<int>g[Max];

void init()
{
int i;
for(i=0;i<=n;i++)
g[i].clear();
}

int DFS(int cur)
{
int i;
for(i=0;i<g[cur].size();i++)
{
int k=g[cur][i];
if(!visit[k])
{
visit[k]=1;
if(match[k]==-1||DFS(match[k]))
{
match[k]=cur;
return 1;
}
}
}
return 0;
}

int solve()
{
int i,num=0;
for(i=1;i<=n;i++)
{
memset(visit,0,sizeof(visit));
if(DFS(i))
num++;
}
return num;
}
int main()
{
int i,j,k,l,m;
scanf("%d%d",&n,&m);
memset(match,-1,sizeof(match));//疯了。。。一开始这个数组没初始化一直跑不出来,太不细心了
while(m--)
{
scanf("%d%d",&i,&j);
g[i].push_back(j);

}
cout<<solve()<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: