POJ 3041 Asteroids 二分匹配

/*题意:输入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;
}


你可能感兴趣的:(POJ 3041 Asteroids 二分匹配)