首页 > 其他 > 详细

Ants POJ - 3565

时间:2020-03-21 15:40:44      阅读:50      评论:0      收藏:0      [点我收藏+]

题意:

题目链接
\(N\)个蚂蚁,\(N\)个苹果,要在每个蚂蚁和一个相应的苹果之间连边,问如何给蚂蚁分配苹果,可以使这些边不相交。\(N<=100\)

思路:

关注两条路径相交的情况
不相交和相交有没有什么区别?
相交的总路径长小于不相交的总路径长
(说起来倒还挺简单的~~)
因此就可做了

具体实现:

我采用的是KM算法,大佬们可以直接上网络流/xyx

注意事项:

除了板子不要敲错,没什么好注意的。。。

code:

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=105;
int n,match[N],fm[N];
int nx[N],ny[N],px[N],py[N];
bool vis1[N],vis2[N];
double w[N][N],slack[N],ep1[N],ep2[N];
inline double dis(int ax,int ay,int bx,int by)
{
    int d=(ax-bx)*(ax-bx)+(ay-by)*(ay-by);
    return sqrt((double)d);
}
bool dfs(int x)
{
    vis1[x]=1;
    for(int i=1;i<=n;++i)
    {
        if(vis2[i]) continue;
        double gap=ep1[x]+ep2[i]-w[x][i];
        if(fabs(gap)<1e-5)
        {
            vis2[i]=1;
            if(match[i]==-1||dfs(match[i]))
            {
                match[i]=x;
                return true;
            }
        }
        else slack[i]=min(slack[i],gap);
    }
    return false;
}
inline void km()
{
    fill(match+1,match+n+1,-1);
    fill(ep2+1,ep2+n+1,0);
    for(int i=1;i<=n;++i)
    {
        ep1[i]=w[i][1];
        for(int j=2;j<=n;++j)
            ep1[i]=max(ep1[i],w[i][j]);
    }
    for(int i=1;i<=n;++i)
    {
        fill(slack+1,slack+n+1,1e9);
        while(1)
        {
            fill(vis1+1,vis1+n+1,0);
            fill(vis2+1,vis2+n+1,0);
            if(dfs(i)) break;
            double d=1e9;
            for(int j=1;j<=n;++j)
                if(!vis2[j]) d=min(d,slack[j]);
            for(int j=1;j<=n;++j)
            {
                if(vis1[j]) ep1[j]-=d;
                if(vis2[j]) ep2[j]+=d;
                else slack[j]-=d;
            }
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d%d",&nx[i],&ny[i]);
    for(int i=1;i<=n;++i)
        scanf("%d%d",&px[i],&py[i]);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            w[i][j]=-dis(nx[i],ny[i],px[j],py[j]);
    km();
    for(int i=1;i<=n;++i)fm[match[i]]=i;
    for(int i=1;i<=n;++i)
        printf("%d\n",fm[i]);
    return 0;
}

Ants POJ - 3565

原文:https://www.cnblogs.com/zmyzmy/p/12539197.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!