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

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

http://poj.org/problem?id=2536

题意:

       有n个地鼠和m个洞,有鹰飞来时,n个地鼠如果能在s秒从当前位置回到一个洞,就能不死,一个洞能容纳一个地鼠,它们的速度为v。求可能死的地鼠个数的最小值。

分析:

       如果一个地鼠能在s秒内到达一个特定的洞,那么就在它们之间两一条无向边. 我们所建立的图是一个二分图,左边是地鼠,右边是洞.

       现在我们要求的就是该图的最大匹配数.

       那么可能死的地鼠个数 = n – 最大匹配数.

AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=100+5;

struct Max_Match
{
    int n,m;
    bool g[maxn][maxn];
    bool vis[maxn];
    int left[maxn];

    void init(int n,int m)
    {
        this->n=n;
        this->m=m;
        memset(g,0,sizeof(g));
        memset(left,-1,sizeof(left));
    }

    bool match(int u)
    {
        for(int v=1;v<=m;v++)if(g[u][v] && !vis[v])
        {
            vis[v]=true;
            if(left[v]==-1 || match(left[v]))
            {
                left[v]=u;
                return true;
            }
        }
        return false;
    }

    int solve()
    {
        int ans=0;
        for(int i=1;i<=m;i++)
        {
            memset(vis,0,sizeof(vis));
            if(match(i)) ans++;
        }
        return ans;
    }
}MM;

struct Point
{
    double x,y;
    void read()
    {
        scanf("%lf%lf",&x,&y);
    }
}P1[maxn],P2[maxn];
double get_dist(int i,int j)
{
    return sqrt( (P1[i].x-P2[j].x)*(P1[i].x-P2[j].x)+(P1[i].y-P2[j].y)*(P1[i].y-P2[j].y) );
}
int main()
{
    int n,m,s,v;
    while(scanf("%d%d%d%d",&n,&m,&s,&v)==4)
    {
        MM.init(n,m);
        for(int i=1;i<=n;i++)
            P1[i].read();
        for(int i=1;i<=m;i++)
            P2[i].read();
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(get_dist(i,j) <= s*v )
            {
                MM.g[i][j]=true;
            }
        }
        printf("%d\n",n-MM.solve());
    }
    return 0;
}

你可能感兴趣的:(Algorithm,算法,ACM)