POJ 2536 Gopher II (二分图最大匹配)

题目链接:http://poj.org/problem?id=2536


题意:有若干只田鼠,给出他们的坐标,有若干个洞,同样给出坐标,当遇到危险时田鼠可以在s秒内跑进一个洞,但一个洞只能容纳一只地鼠,给出田鼠的速度v,问遇到危险最多有多少只田鼠可以进洞


思路:如果田鼠i与地洞j的距离少于s*v,则代表它可以进入该洞,G[i][j]=1,建立二分图,用匈牙利算法求最大匹配


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
//#include <cmath>
#define maxn 130
#define eps 0.00000001
using namespace std;

double x1[maxn],y1[maxn],x2[maxn],y2[maxn];
int G[maxn][maxn],list[maxn],vis[maxn];
int n,m,s,vv;

int check(int u,int v)
{
    double dis=(x1[u]-x2[v])*(x1[u]-x2[v])+(y1[u]-y2[v])*(y1[u]-y2[v]);
   // cout<<dis<<"::::"<<s*s<<endl;
    if (dis<=s*s*vv*vv) return 1;

    else return 0;
}

int find(int u)
{
    for (int i=0;i<m;i++)
    {
        if (G[u][i]==1 && vis[i]==0)
        {
            vis[i]=1;
            if (list[i]==-1 || find(list[i]))
            {
                list[i]=u;
                return 1;
            }
        }
    }
    return 0;
}

int hungry()
{
    int sum=0;
    for (int i=0;i<n;i++)
    {
        memset(vis,0,sizeof(vis));
        if (find(i)) sum++;
    }
    return sum;
}



int main()
{

    while (scanf("%d%d%d%d",&n,&m,&s,&vv)!=EOF)
    {
        memset(G,0,sizeof(G));
        memset(list,-1,sizeof(list));
        for (int i=0;i<n;i++)
        {
            scanf("%lf%lf",&x1[i],&y1[i]);
        }

        for (int j=0;j<m;j++)
        {
            scanf("%lf%lf",&x2[j],&y2[j]);
        }

        for (int i=0;i<n;i++)
        {
            for (int j=0;j<m;j++)
            {
                if (check(i,j))
                {
                   G[i][j]=1;//cout<<i<<":"<<j<<endl;
                }
            }
        }
        int res=n-hungry();
        printf("%d\n",res);
    }
}


你可能感兴趣的:(ACM,poj,图论)