POJ-3565 Ants---KM算法+slack优化
题目链接:
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优化的更多相关文章
- poj3565 Ants km算法求最小权完美匹配,浮点权值
/** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...
- poj 3565 uva 1411 Ants KM算法求最小权
由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...
- POJ 3565 Ants 【最小权值匹配应用】
传送门:http://poj.org/problem?id=3565 Ants Time Limit: 5000MS Memory Limit: 65536K Total Submissions: ...
- KM算法及其优化的学习笔记&&bzoj2539: [Ctsc2000]丘比特的烦恼
感谢 http://www.cnblogs.com/vongang/archive/2012/04/28/2475731.html 这篇blog里提供了3个链接……基本上很明白地把KM算法是啥讲清楚 ...
- POJ 3565 Ants(最佳完美匹配)
Description Young naturalist Bill studies ants in school. His ants feed on plant-louses that live on ...
- poj 3565 ants
/* poj 3565 递归分治 还有用KM的做法 这里写的分治 按紫书上的方法 不过那里说的有点冗杂了 可以简化一下 首先为啥可以分治 也就是分成子问题解决 只要有一个集合 黑白的个数相等 就一定能 ...
- 【POJ3565】ANTS KM算法
[POJ3565]ANTS 题意:平面上有2*n个点,N白N黑.为每个白点找一个黑点与之连边,最后所有边不交叉.求一种方案. 题解:KM算法真是一个神奇的算法,虽然感觉KM能做的题用费用流都能做~ 本 ...
- poj 2565 Ants (KM+思维)
Ants Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4125 Accepted: 1258 Special Ju ...
- POJ 3565 Ants (最小权匹配)
题意 给出一些蚂蚁的点,给出一些树的点,两两对应,使他们的连线不相交,输出一种方案. 思路 一开始没想到怎么用最小权匹配--后来发现是因为最小权匹配的方案一定不相交(三角形两边之和大于第三边)--还是 ...
随机推荐
- 将图片至于jsp页面上(层)
<div style="position: relative"> <span style="position: relative; top: 1px; ...
- 使用combobox下拉列表框实现省 市 县 的三级联动
package com.hanqi.entity; //地区 public class Region { //地区id private String regionID; //地区名称 private ...
- LightOJ 1336 - Sigma Function
原题链接 基础数论中很经典的一道题 题意 给出了σ(n)的计算公式,让你找出整数1-n中有多少对应σ(n)的值是偶数. 思路 观察σ(n)的公式发现,每一个乘项都是 (piei+1 - 1) / (p ...
- php路径问题
./ 是在当前目录开始寻找文件/ 是在下一级目录开始寻找文件 ../ 这个是在上一级目录开始寻找文件 $_SERVER['DOCUMENT_ROOT']获取站点根目录 __FILE__获取当前文件的完 ...
- Exadata 上关于SAS盘的小秘密
案例概述 一个X3-2 的Exadata临时客户,ORACLE原厂工程师在进行onecommand初始化的过程中,执行到第6步,calibrate检测存储节点磁盘性能时报错,后续工作无法继续.而由于一 ...
- (反NIM)
题目大意是和普通的NIM游戏一样,但是却是取到最后一个是输的,天真的以为就是反过来,其实并不是这样的 结论 先手必胜的条件为 ①:所有堆的石子数均=1,且有偶数堆. ②:至少有一个堆的石子数>1 ...
- myeclipse编辑jsp页面卡
现象 但是遇到了一种情况,编辑jsp页面卡,尤其是使用快捷键ctrl+ 时会很卡. 编辑java页面没问题的,比较流畅. 在jsp页面中一点ctrl+ 就卡几秒钟. 按照上篇文章中优化过后只是编辑j ...
- Sorted Subsegments
https://www.hackerrank.com/contests/101hack38/challenges/sorted-subsegments/problem 首先要注意到可以二分答案,比如当 ...
- Linux Shell命令系列(2)
6. history命令 “history”命令就是历史记录.它显示了在终端中所执行过的所有命令的历史. 7. sudo命令 “sudo”(super user do)命令允许授权用户执行超级用户或者 ...
- (转)linux 中使用ls指定输出时间格式
linux 中使用ls指定输出时间格式 原文:http://blog.csdn.net/chaofanwei/article/details/13018753 ls -l --time-style=x ...