美文网首页GraphTheory
POJ-3565-Ants(二分图最优匹配)

POJ-3565-Ants(二分图最优匹配)

作者: 雨落八千里 | 来源:发表于2019-08-20 22:18 被阅读1次

Ants

题意:

  • n个蚂蚁群,n棵苹果树,怎样分配(一对一分配)使得它们直接没有交集?

思路:


  • 如图根据三角形三边关系可以得出AC+BD<AD+BD
  • 这个是找最小权值的最优分配。我们已经会最大权值的最优匹配了,怎样找最小匹配呢?把权值改成对应的负值,我们之前的最大匹配求出的的权值就不是最小的值了,那把负值的最大匹配求出来就不是正值的最小值了哈哈哈哈
    注意:scalk数组是double,不能使用memset函数赋值INF
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
const double esp=1e-6;
struct node
{
    double x,y;
} pointant[110],pointtree[110];
double edge[110][110];
double exant[110];
double extree[110];
int visant[110];
int vistree[110];
int match[110];
double scalk[110];
int n;
bool Hungarian(int tree)
{
    vistree[tree]=1;
    for(int ant=1; ant<=n; ant++)
    {
        if(visant[ant])
        {
            continue;
        }
        double tep=exant[ant]+extree[tree]-edge[tree][ant];
        if(abs(tep)<esp)
        {
            visant[ant]=1;
            if(match[ant]==-1||Hungarian(match[ant]))
            {
                match[ant]=tree;
                return true;
            }
        }
        else
        {
            if(tep<scalk[ant])
            {
                scalk[ant]=tep;
            }

        }
    }
    return false;
}
void KM( )
{
    memset(match,-1,sizeof(match));
    memset(exant,0,sizeof(exant));
    for(int i=1; i<=n; i++)
    {
        extree[i]=edge[i][1];
        for(int j=2; j<=n; j++)
        {
            if(edge[i][j]>extree[i])
            {
                extree[i]=edge[i][j];
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1;j<=n;j++)//double不能用memset函数赋值INF
        {
            scalk[j]=INF;
        }
        while(1)
        {
            memset(visant,0,sizeof(visant));
            memset(vistree,0,sizeof(vistree));
            if(Hungarian(i))
            {
                break;
            }
            //cout<<"flag"<<endl;
            double d=INF;
            for(int j=1; j<=n; j++)
            {
                if(!visant[j])
                {
                    if(d>scalk[j])
                    {
                        d=scalk[j];
                    }
                }
            }
            for(int j=1; j<=n; j++)
            {
                if(vistree[j])
                {
                    extree[j]-=d;
                }
                if(visant[j])
                {
                    exant[j]+=d;
                }
                else
                {
                    scalk[j]-=d;
                }

            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        printf("%d\n",match[i]);
    }
    return ;
}
double add(node a,node b)
{
    return -sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));//把正值改成负的
}
int main( )
{
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%lf%lf",&pointant[i].x,&pointant[i].y);
        }
        for(int i=1; i<=n; i++)
        {
            scanf("%lf%lf",&pointtree[i].x,&pointtree[i].y);
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                edge[i][j]=add(pointtree[i],pointant[j]);
            }
        }
        KM( );
    }
    return 0;
}

相关文章

  • POJ-3565-Ants(二分图最优匹配)

    Ants题意:个蚂蚁群,棵苹果树,怎样分配(一对一分配)使得它们直接没有交集?思路:如图根据三角形三边关系可以得出...

  • 二分图

    二分图判定: 题目链接:二分图判定 dfs: 最大匹配: 题目链接:最大匹配-匈牙利算法 dfs: 二维最大匹配:...

  • 二分图最优匹配「KM算法」

    KM算法用来求二分图最大权完美匹配一般对KM算法的描述,基本上可以概括成以下几个步骤:(1) 初始化可行标杆(2)...

  • KM算法( 一 )

    A - 奔小康赚大钱题意:求解二分图的最优匹配 B - Going Home题意:给你一个N行M列的矩阵,其中“....

  • 二分匹配 专题整理

    二分匹配学习记录 参考资料 二分图讲解及匈牙利模板 HDU 2444 题意 给出图,求是否二分图,和二分图的最大匹...

  • 【算法篇】二分图匹配之匈牙利算法

    二分图匹配,自然要先从定义入手,那么二分图是什么呢? 二分图: 二分图又称作二部图,是图论中的一种特殊模型。 设G...

  • 2021-10-12leetcode

    快速加 快速幂 二分图的最大匹配 一次A掉

  • 【实战笔记】二分图匹配算法详解

    本笔记主要用于记录与二分图匹配有关的实战。

  • 二分图最大匹配

    题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式第一行,n,m...

  • 二分图最大匹配

    匈牙利算法

网友评论

    本文标题:POJ-3565-Ants(二分图最优匹配)

    本文链接:https://www.haomeiwen.com/subject/plgmsctx.html