题目链接:

https://vjudge.net/problem/POJ-3565

题目大意:

在坐标系中有N只蚂蚁,N棵苹果树,给你蚂蚁和苹果树的坐标。让每只蚂蚁去一棵苹果树,

一棵苹果树对应一只蚂蚁。这样就有N条直线路线,问:怎样分配,才能使总路程和最小,且

N条线不相交。

解题思路:

用一个图来说明思路。

假设A、B为蚂蚁,C、D为苹果树。则存在两种匹配:第一种是AD、BC,第二种是AC、BD。

根据三角形不等式AD+BC < AC+BD,最后得到很重要的一个性质——满足总路程之和最小

的方案一定不相交。现在来构建二分图,一边为蚂蚁,另一边为苹果树,以距离为边权值,题

目就变为了求带权二分图最小权和的最佳匹配。反向来思考,将距离乘以-1取负值建图,那么

就变为了求带权二分图最大权和的最佳匹配。直接用KM算法来做。

注意:用double,用slack数组优化(比全局变量快很多,网上看到说对于完全图优化会很快,用全局变量代替slack数组就超时)

 #include<iostream>
#include<vector>
#include<cstring>
#include<queue>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn = + ;
const int INF = 0x3f3f3f3f;
double Map[maxn][maxn];
double wx[maxn], wy[maxn];//顶标值
int cx[maxn], cy[maxn];
//cx[i]表示与x部的点i匹配的y部的点的编号
//cy[i]表示与y部的点i匹配的x部的点的编号
bool visx[maxn], visy[maxn];//标记y部的点是否加入增广路
int cntx, cnty;//x部点的数目和y部点的数目
double minz;//边权顶标最小值
double slack[maxn];
bool dfs(int u)//进入的都是X部的点
{
visx[u] = ;
for(int v = ; v <= cnty; v++)
{
if(!visy[v] && Map[u][v] != INF)
{
double t = wx[u] + wy[v] - Map[u][v];
if(fabs(t) < 1e-)
{
visy[v] = ;
if(cy[v] == - || dfs(cy[v]))
{
cx[u] = v;
cy[v] = u;
return true;
}
}
else if(slack[v] > t)
slack[v] = t;
}
}
return false;
} void KM()
{
memset(cx, -, sizeof(cx));
memset(cy, -, sizeof(cy));
memset(wy, , sizeof(wy));
for(int i = ; i <= cntx; i++)wx[i] = -1.0 * INF;
for(int i = ; i <= cntx; i++)
{
for(int j = ; j <= cnty; j++)
{
wx[i] = max(wx[i], Map[i][j]);
}
}
for(int i = ; i <= cntx; i++)
{
for(int j = ; j <= cnty; j++)
slack[j] = INF;
while()
{
minz = 1.0 * INF;
memset(visx, , sizeof(visx));
memset(visy, , sizeof(visy));
if(dfs(i))break;
double d = INF;
for(int i = ; i <= cnty; i++)
if(!visy[i] && d > slack[i])
d = slack[i];
for(int j = ; j <= cntx; j++)
if(visx[j])wx[j] -= d;
for(int j = ; j <= cnty; j++)
if(visy[j])wy[j] += d;
else slack[j] -= d;
}
}
for(int i = ; i <= cntx; i++)
printf("%d\n", cx[i]);
}
struct node
{
double x, y;
}a[maxn], b[maxn];
double dis(node a, node b)
{
return -sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main()
{
int n;
scanf("%d", &n);
cntx = cnty = n;
for(int i = ; i <= n; i++)scanf("%lf%lf", &a[i].x, &a[i].y);
for(int i = ; i <= n; i++)scanf("%lf%lf", &b[i].x, &b[i].y);
for(int i = ; i <= n; i++)
{
for(int j = ; j <= n; j++)
Map[i][j] = dis(a[i], b[j]);
}
KM();
}

POJ-3565 Ants---KM算法+slack优化的更多相关文章

  1. poj3565 Ants km算法求最小权完美匹配,浮点权值

    /** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...

  2. poj 3565 uva 1411 Ants KM算法求最小权

    由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...

  3. POJ 3565 Ants 【最小权值匹配应用】

    传送门:http://poj.org/problem?id=3565 Ants Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: ...

  4. KM算法及其优化的学习笔记&&bzoj2539: [Ctsc2000]丘比特的烦恼

    感谢  http://www.cnblogs.com/vongang/archive/2012/04/28/2475731.html 这篇blog里提供了3个链接……基本上很明白地把KM算法是啥讲清楚 ...

  5. POJ 3565 Ants(最佳完美匹配)

    Description Young naturalist Bill studies ants in school. His ants feed on plant-louses that live on ...

  6. poj 3565 ants

    /* poj 3565 递归分治 还有用KM的做法 这里写的分治 按紫书上的方法 不过那里说的有点冗杂了 可以简化一下 首先为啥可以分治 也就是分成子问题解决 只要有一个集合 黑白的个数相等 就一定能 ...

  7. 【POJ3565】ANTS KM算法

    [POJ3565]ANTS 题意:平面上有2*n个点,N白N黑.为每个白点找一个黑点与之连边,最后所有边不交叉.求一种方案. 题解:KM算法真是一个神奇的算法,虽然感觉KM能做的题用费用流都能做~ 本 ...

  8. poj 2565 Ants (KM+思维)

    Ants Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4125   Accepted: 1258   Special Ju ...

  9. POJ 3565 Ants (最小权匹配)

    题意 给出一些蚂蚁的点,给出一些树的点,两两对应,使他们的连线不相交,输出一种方案. 思路 一开始没想到怎么用最小权匹配--后来发现是因为最小权匹配的方案一定不相交(三角形两边之和大于第三边)--还是 ...

随机推荐

  1. 将图片至于jsp页面上(层)

    <div style="position: relative"> <span style="position: relative; top: 1px; ...

  2. 使用combobox下拉列表框实现省 市 县 的三级联动

    package com.hanqi.entity; //地区 public class Region { //地区id private String regionID; //地区名称 private ...

  3. LightOJ 1336 - Sigma Function

    原题链接 基础数论中很经典的一道题 题意 给出了σ(n)的计算公式,让你找出整数1-n中有多少对应σ(n)的值是偶数. 思路 观察σ(n)的公式发现,每一个乘项都是 (piei+1 - 1) / (p ...

  4. php路径问题

    ./ 是在当前目录开始寻找文件/ 是在下一级目录开始寻找文件 ../ 这个是在上一级目录开始寻找文件 $_SERVER['DOCUMENT_ROOT']获取站点根目录 __FILE__获取当前文件的完 ...

  5. Exadata 上关于SAS盘的小秘密

    案例概述 一个X3-2 的Exadata临时客户,ORACLE原厂工程师在进行onecommand初始化的过程中,执行到第6步,calibrate检测存储节点磁盘性能时报错,后续工作无法继续.而由于一 ...

  6. (反NIM)

    题目大意是和普通的NIM游戏一样,但是却是取到最后一个是输的,天真的以为就是反过来,其实并不是这样的 结论 先手必胜的条件为 ①:所有堆的石子数均=1,且有偶数堆. ②:至少有一个堆的石子数>1 ...

  7. myeclipse编辑jsp页面卡

    现象 但是遇到了一种情况,编辑jsp页面卡,尤其是使用快捷键ctrl+ 时会很卡. 编辑java页面没问题的,比较流畅. 在jsp页面中一点ctrl+  就卡几秒钟. 按照上篇文章中优化过后只是编辑j ...

  8. Sorted Subsegments

    https://www.hackerrank.com/contests/101hack38/challenges/sorted-subsegments/problem 首先要注意到可以二分答案,比如当 ...

  9. Linux Shell命令系列(2)

    6. history命令 “history”命令就是历史记录.它显示了在终端中所执行过的所有命令的历史. 7. sudo命令 “sudo”(super user do)命令允许授权用户执行超级用户或者 ...

  10. (转)linux 中使用ls指定输出时间格式

    linux 中使用ls指定输出时间格式 原文:http://blog.csdn.net/chaofanwei/article/details/13018753 ls -l --time-style=x ...