/**
题目:poj3565 Ants km算法求最小权完美匹配,浮点权值。
链接:http://poj.org/problem?id=3565
题意:给定n个白点的二维坐标,n个黑点的二维坐标。
求是否存在n条边,每条边恰好连一个白点,一个黑点,且所有的边不相交。
输出所有黑点连接的白点编号。 思路:最小权完美匹配。
假定有白点1(a1,b1), 2(a2,b2), 黑点3(a3,b3),4(a4,b4);
如果1(a1,b1)与3(a3,b3)相连,2(a2,b2)与4(a4,b4)相连,如果他们两条边相交,那么dis(1,3)+dis(2,4)
一定大于dis(1,4)+dis(2,3)这两条没有相交的边长和。所以应该连接1-4,2-3; 如果存在满足题目要求的解,那么求一个最小权完美匹配,就可以保证所有匹配的边不相交。 坑点:题目给的坐标有浮点数。 要注意题目输出要求,1~n的黑点对应的白点编号,那么让白点在左边,黑点在右边。输出结果从match获取值即可。 ps:求两点距离我没有开根号情况下,wa。。难道是精度卡了~~~?
*/ #include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = ;
const int INF = 0x3f3f3f3f;
const double eps = 1e-;
double love[MAXN][MAXN]; // 记录每个妹子和每个男生的好感度
double ex_girl[MAXN]; // 每个妹子的期望值
double ex_boy[MAXN]; // 每个男生的期望值
bool vis_girl[MAXN]; // 记录每一轮匹配匹配过的女生
bool vis_boy[MAXN]; // 记录每一轮匹配匹配过的男生
int match[MAXN]; // 记录每个男生匹配到的妹子 如果没有则为-1
double slack[MAXN]; // 记录每个汉子如果能被妹子倾心最少还需要多少期望值 int N;//左侧顶点数=右侧顶点数=N; bool dfs(int girl)
{
vis_girl[girl] = true; for (int boy = ; boy < N; ++boy) { if (vis_boy[boy]) continue; // 每一轮匹配 每个男生只尝试一次 double gap = ex_girl[girl] + ex_boy[boy] - love[girl][boy]; if (fabs(gap)<=eps) { // 如果符合要求,注意浮点啊。
vis_boy[boy] = true;
if (match[boy] == - || dfs( match[boy] )) { // 找到一个没有匹配的男生 或者该男生的妹子可以找到其他人
match[boy] = girl;
return true;
}
} else {
slack[boy] = min(slack[boy], gap); // slack 可以理解为该男生要得到女生的倾心 还需多少期望值 取最小值 备胎的样子【捂脸
}
} return false;
} double KM()
{
memset(match, -, sizeof match); // 初始每个男生都没有匹配的女生
memset(ex_boy, , sizeof ex_boy); // 初始每个男生的期望值为0 // 每个女生的初始期望值是与她相连的男生最大的好感度
for (int i = ; i < N; ++i) {
ex_girl[i] = love[i][];
for (int j = ; j < N; ++j) {
ex_girl[i] = max(ex_girl[i], love[i][j]);
}
} // 尝试为每一个女生解决归宿问题
for (int i = ; i < N; ++i) { fill(slack, slack + N, INF); // 因为要取最小值 初始化为无穷大 while () {
// 为每个女生解决归宿问题的方法是 :如果找不到就降低期望值,直到找到为止 // 记录每轮匹配中男生女生是否被尝试匹配过
memset(vis_girl, false, sizeof vis_girl);
memset(vis_boy, false, sizeof vis_boy); if (dfs(i)) break; // 找到归宿 退出 // 如果不能找到 就降低期望值
// 最小可降低的期望值
double d = INF;
for (int j = ; j < N; ++j)
if (!vis_boy[j]) d = min(d, slack[j]); for (int j = ; j < N; ++j) {
// 所有访问过的女生降低期望值
if (vis_girl[j]) ex_girl[j] -= d; // 所有访问过的男生增加期望值
if (vis_boy[j]) ex_boy[j] += d;
// 没有访问过的boy 因为girl们的期望值降低,距离得到女生倾心又进了一步!
else slack[j] -= d;
}
}
} // 匹配完成 求出所有配对的好感度的和
double res = ;
for (int i = ; i < N; ++i)
res += love[ match[i] ][i]; return res;
}
struct node
{
double x, y;
}a[MAXN],b[MAXN];
double dis(int i,int j)
{
return sqrt((b[i].x-a[j].x)*(b[i].x-a[j].x)+(b[i].y-a[j].y)*(b[i].y-a[j].y));
}
int main()
{
while (~scanf("%d", &N)) {//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)
love[i][j] = -dis(i,j); //printf("%d\n", KM());
KM();
for(int i = ; i < N; i++){
printf("%d\n",match[i]+);
}
}
return ;
}

poj3565 Ants km算法求最小权完美匹配,浮点权值的更多相关文章

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

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

  2. 【POJ 2195】 Going Home(KM算法求最小权匹配)

    [POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  3. 二分图学习记 之 KM算法 二分图最大权完美匹配。

    前置知识 :匈牙利算法 首先有这样一张图,求这张图的最大权完美匹配. 当然如果你不想看这些渣图的话,您可以转到 洛谷 运动员最佳匹配问题 下面我来强行解释一下KM算法 左边一群妹子找汉子,但是每个妹子 ...

  4. uva 1411 Ants (权值和最小的完美匹配---KM算法)

    uva 1411 Ants Description Young naturalist Bill studies ants in school. His ants feed on plant-louse ...

  5. hdu1533 Going Home km算法解决最小权完美匹配

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  6. POJ-2195 Going Home---KM算法求最小权值匹配(存负边)

    题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格 ...

  7. UVA 1349 Optimal Bus Route Design (二分图最小权完美匹配)

    恰好属于一个圈,那等价与每个点有唯一的前驱和后继,这让人想到了二分图, 把一个点拆开,点的前驱作为S集和点的后继作为T集,然后连边,跑二分图最小权完美匹配. 写的费用流..最大权完美匹配KM算法没看懂 ...

  8. UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design

    题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi  ...

  9. POJ 2404 Jogging Trails(最小权完美匹配)

    [题目链接] http://poj.org/problem?id=2404 [题目大意] 给出一张图,求走遍所有的路径至少一次,并且回到出发点所需要走的最短路程 [题解] 如果图中所有点为偶点,那么一 ...

随机推荐

  1. Cocos2d-x3.0游戏实例之《别救我》第七篇——物理世界的碰撞检測

    事实上我也非常吃惊-居然写到第七篇了,我估计也就是四篇的内容,感觉非常奇妙,我也不会非常唠叨什么吖);    // 0001 );   // 0001 ); // 0001 这样我们才干监听到它们的碰 ...

  2. minic 动作句型处理

    #include "lex_define.h" enum keywords_type//代表一些关键字 { loop_for=,//代表for关键字 loop_while,//代表 ...

  3. JMeter 一:Elements of a Test Plan

    参考:http://jmeter.apache.org/usermanual/test_plan.html 最小测试集包括:Test Plan,一个Thread Group,以及一个或多个Sample ...

  4. wamp server php环境绑定域名

    思路: 用花生壳做动态域名解析 用wamp server 在本机上做一个 php web server; 这样就可以让一台内网电脑做一个测试用的服务器: 一:wamp server php环境绑定域名 ...

  5. Angular 监听路由变化事件

    摘要: $stateChangeStart- 当模板开始解析之前触发 $rootScope.$on('$stateChangeStart', function(event, toState, toPa ...

  6. 算法笔记_097:蓝桥杯练习 算法提高 P1001(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 当两个比较大的整数相乘时,可能会出现数据溢出的情形.为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法.具体来说,首先以字符串的形式输入两个整 ...

  7. C++ STL中允许重复key的multimap

    在实际的项目中可能会碰到key重复的情况,正常的MAP类型是不允许重复的key,所以就要使用multimap了,multimap的使用和map基本类似,可以无缝对接 #include <map& ...

  8. C++ 代码风格准则:POD

    作者:一根筋的傻瓜链接:https://www.zhihu.com/question/36379130/answer/69853366来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  9. 如何更改Docker默认的images存储位置

    Docker的镜像以及一些数据都是在/var/lib/docker目录下,它占用的是Linux的系统分区,也就是下面的/dev/vda1,当有多个镜像时,/dev/vda1的空间可能不足,我们可以把d ...

  10. Objective-C之定义函数

    Demo1.m 一个基础的函数定义 #import<Foundation/Foundation.h> //定义一个返回值为int类型的,名为max的函数.传入的参数为两个int型数据 in ...