题目链接:

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. 空字符串‘’ null false 区别

    1.''空字符串 .null 和false都是以值为0来存储的   只是数据结构不一致而已 空字符串------字符串数据格式 null -----------null数据格式 false ----- ...

  2. vue -- 插件的开发与使用

    开发插件 插件通常会为 Vue 添加全局功能.插件的范围没有限制--一般有下面几种: 1.添加全局方法或者属性,如: vue-custom-element. 2.添加全局资源:指令/过滤器/过渡等,如 ...

  3. python之05 操作系统用户密码修改

    ubuntu的操作系统修改密码的操作方法: 一.在系统启动时按住shift键,出现下图的界面 二.按下e进入命令行,找到下图红色框中的文字并修改成rw init=/bin/bash 然后按F10启动, ...

  4. GoWeb开发_Iris框架讲解(四):Iris框架设置操作

    路由组的使用 在实际开发中,我们通常都是按照模块进行开发,同一模块的不同接口url往往是最后的一级url不同,具有相同的前缀url.因此,我们期望在后台开发中,可以按照模块来进行处理我们的请求,对于这 ...

  5. 从零开始安装 Ambari (2) -- 准备本地 repository

    安装 Ambari,最后是为了用它部署 hadoop 集群.安装时默认使用的是 hortonworks 远程的资源,用它部署集群时,需要下载 Hadoop.Hive.HBase 的安装包,速度很慢.我 ...

  6. 洛谷P1164 小A点菜(01背包求方案数)

    P1164 小A点菜 题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过u ...

  7. Java快速向数据库中插入大量数据 比如10万条以上

    String sql = "insert into table *****"; //必须要有这句,要不然效果不明显 con.setAutoCommit(false); ps = c ...

  8. [USACO07MAR]黄金阵容均衡Gold Balanced L… map

    题目描述 Farmer John's N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been able to na ...

  9. BestCoder Round #86 1001

    链接http://acm.hdu.edu.cn/showproblem.php?pid=5804 题意:给你一些商店和他的商品价格,然后给你一个记账本,问你记大了就是1,否则是0 解法:模拟,注意测试 ...

  10. 设计模式——抽象工厂(Abstract Factory)

    提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类. ——DP UML类图 模式说明 抽象工厂与工厂方法在定义上最明显的区别是“创建一系列相关或相互依赖对象的接口”,由此可以看出抽象工 ...