题目:http://poj.org/problem?id=3565

首先,我们神奇地发现,没有相交边的匹配可以转化为距离和最小的匹配,所以可以使用KM算法求带权匹配;

要求的是距离和最小,所以把边权转化成负值来求最大;

KM算法有点难理解,看了许多博客,总算朦胧懂了:

首先,每个点有一个“顶标”,用来计算边权和,起初所有左部点的顶标都为相连边的最大边权,右部点的为0;

两个点匹配成功,仅当其顶标和等于其边权(所以可以通过调整顶标来控制边权);

一次dfs没有成功返回0时,我们已经记录下它经过的所有点,这些点都满足“其顶标和等于其边权”条件,组成了一个相等子图;

然而此时的相等子图无法使遍历到的这个左部点得到匹配,所以需要调整顶标;

可知最终的匹配中顶标和等于边权和,为了让顶标和下降最少而又有可能使这个点得到匹配,我们在所有相等子图中的左部点和不在相等子图中的右部点之间找到距离满足条件最小的差值,这样根据它调整顶标后,顶标和下降最少,而又至少会多出这一组可行的点加入相等子图;

这样重复进行,直到这个左部点匹配成功;

最后匹配的权值和是现在的顶标和,这个顶标和比起一开始我们期望的和(每个左部点顶标为其所连最大的边)有所下调,但我们保证每次下调量最少,所以得到最优匹配。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
double const inf=999999.999999,eps=1e-;
int const MAXN=;
int n,pre[MAXN],ans[MAXN],xa[MAXN],xb[MAXN],ya[MAXN],yb[MAXN];
double dis[MAXN][MAXN],la[MAXN],lb[MAXN];
bool va[MAXN],vb[MAXN];
bool dfs(int x)
{
va[x]=;
for(int i=;i<=n;i++)
if(!vb[i]&&fabs(la[x]+lb[i]-dis[x][i])<eps)
{
vb[i]=;
if(!pre[i]||dfs(pre[i]))
{pre[i]=x;return ;}
}
return ;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d%d",&xa[i],&ya[i]);
for(int i=;i<=n;i++)
scanf("%d%d",&xb[i],&yb[i]);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
dis[i][j]=-sqrt(1.0*(xa[i]-xb[j])*(xa[i]-xb[j])+1.0*(ya[i]-yb[j])*(ya[i]-yb[j]));
memset(la,-0x3f,sizeof la);
for(int i=;i<=n;i++)
{
la[i]=dis[i][];
for(int j=;j<=n;j++)
la[i]=max(la[i],dis[i][j]);
}
for(int i=;i<=n;i++)
{
while()
{
memset(va,,sizeof va);
memset(vb,,sizeof vb);
if(dfs(i))break;
double tmp=inf;
for(int i=;i<=n;i++) if(va[i])
for(int j=;j<=n;j++) if(!vb[j])
tmp=min(tmp,la[i]+lb[j]-dis[i][j]);
for(int i=;i<=n;i++)
{
if(va[i])la[i]-=tmp;
if(vb[i])lb[i]+=tmp;
}
}
}
for(int i=;i<=n;i++)
ans[pre[i]]=i;
for(int i=;i<=n;i++)
printf("%d\n",ans[i]);
return ;
}

poj3565Ants——KM算法的更多相关文章

  1. 匈牙利算法与KM算法

    匈牙利算法 var i,j,k,l,n,m,v,mm,ans:longint; a:..,..]of longint; p,f:..]of longint; function xyl(x,y:long ...

  2. 【HDU2255】奔小康赚大钱-KM算法

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description ...

  3. HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

    二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...

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

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

  5. poj 2195 KM算法

    题目链接:http://poj.org/problem?id=2195 KM算法模板~ 代码如下: #include "stdio.h" #include "string ...

  6. hdu 2255 奔小康赚大钱--KM算法模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...

  7. HDU(2255),KM算法,最大权匹配

    题目链接 奔小康赚大钱 Time Limit: 1000/1000MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  8. 二分图 最大权匹配 km算法

    这个算法的本质还是不断的找增广路: KM算法的正确性基于以下定理:若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最 ...

  9. hdu 2255 奔小康赚大钱 KM算法

    看到这么奇葩的题目名我笑了,后来这么一个裸的KM调了2小时我哭了…… 这是个裸的KM算法,也没什么多说的,主要是注意多组数据时,每次都要把各种数组清空啊,赋值啊什么的,反正比较麻烦.至于为什么调了2小 ...

随机推荐

  1. mysql 修改表引擎方法

    修改表引擎方法 方法1:修改mysql.ini配置文件,重启mysql服务生效 修改my.ini,在[mysqld]下加上default-storage-engine=INNODB 其中红色字体部分是 ...

  2. SDUT 1068-Number Steps(数学:直线)

    Number Steps Time Limit: 1000ms   Memory limit: 10000K  有疑问?点这里^_^ 题目描写叙述 Starting from point (0,0) ...

  3. caffe搭建以及初步学习--win7-vs2013-gtx650tiboost-cuda8.0-cifar10训练和测试-2-快速解决方案cifar10_quick_solver.prototxt

    首先安装好显卡----已经装好了?喜大普奔!没装好?那就用cpu,也是一样的. 拷贝cudnn v5.0 头文件和库文件以及执行文件到cuda8中 -------------------------- ...

  4. java线程中断[interrupt()函数] (转载)

    一个正常的线程中断: 从运行到真正的结束,应该有三个阶段: 正常运行. 处理结束前的工作,也就是准备结束. 结束退出. Java曾经提供过抢占式限制中断,但问题多多,例如的Thread.stop.另一 ...

  5. 手机QQ后台清理不掉的秘密——anddroid悬浮窗

    问题来自于一篇文章:手机QQ后台为何清不掉?MIUIproject师:全靠1像素的页面保命 出于好奇,想知道这一像素究竟是啥东西,用手机安全管家控制QQ的悬浮窗权限: 关闭QQ的悬浮窗权限,通过后台一 ...

  6. mysql-connector-java与mysql版本的对应

    记录下mysql-connector-java与mysql版本的对应关系,已方便以后参考,这是最新版本对应, 时间:2017年5月23日 官网文档地址: https://dev.mysql.com/d ...

  7. 【BZOJ3041】水叮当的舞步 迭代深搜IDA*

    [BZOJ3041]水叮当的舞步 Description 水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变.为了讨好她的偶像虹猫,水叮当决定在地毯上跳 ...

  8. memcached和一致性hash算法

    1 一致性hash算法的一致性 这里的一致性指的是该算法可以保持memcached和数据库中的数据的一致性. 2 什么是一致性hash算法 2.1 为什么需要一致性hash算法 现在有大量的key v ...

  9. wepy开发

    工欲善其事必先利其器 ide安装.配置] https://tencent.github.io/wepy/document.html VS Code   1. 在 Code 里先安装 Vue 的语法高亮 ...

  10. java的多生产者多消费者例子

    import java.util.concurrent.locks.*; public class Test9 { public static void main(String[] args) { / ...