poj 3565 uva 1411 Ants KM算法求最小权
由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了……
有两种事物,不难想到用二分图。这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案。为啥呢?因为如果有四个点,a,b,c,d 。Ab和cd交叉,ac和bd不交叉,那么ac和bd的长度和一定小于ab和cd的长度和,可以画一个图很容易就证出来。所以,如果所有的边都不交叉,又因为有解,那么最小的权值和就是解了。附图一枚,自己画的,比较简陋,凑活着看吧……
用KM算法求最佳完美匹配最小权值和,可以直接把所有的权值转成负值,在求最大权值和,但是这种方法我觉得有些不对劲,但是不知道在哪里= =,上网一查,才发现这种方法只能用于x和y数量相同的时候,正统做法应该是用一个很大的数减去每个权值,再求最大权值和。PS:我用的是取反的方法……
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #define N 110 struct sss {int x,y; }white[N],black[N]; int n,vx[N],vy[N],fa[N]; double w[N][N],px[N],py[N],str[N]; double dis(int i,int j) {return sqrt((double)(black[i].x-white[j].x)*(black[i].x-white[j].x)+(double)(black[i].y-white[j].y)*(black[i].y-white[j].y)); } int find(int now) {int i,j,k;if (now==0)return 1;vx[now]=1;for (i=1;i<=n;i++){if (!vy[i]&&fabs(px[now]+py[i]-w[now][i])<0.00001){vy[i]=1;if (fa[i]==0||find(fa[i])){fa[i]=now;return 1;}}elseif (str[i]>px[now]+py[i]-w[now][i])str[i]=px[now]+py[i]-w[now][i];}return 0; } void KM() {int i,j,k,x,y,z;double na;memset(fa,0,sizeof(fa));for (i=1;i<=n;i++){memset(str,0x7f,sizeof(str));while (1){memset(vx,0,sizeof(vx));memset(vy,0,sizeof(vy));if (find(i))break;na=0x7f;for (j=1;j<=n;j++)if (!vy[j]&&na>str[j])na=str[j];for (j=1;j<=n;j++){if (vx[j])px[j]-=na;if (vy[j])py[j]+=na;elsestr[j]-=na;}}} } int main() {int i,j,k,x,y,z;z=0;while(scanf("%d",&n)!=EOF){if (z)printf("\n");elsez=1;for (i=1;i<=n;i++)px[i]=-100000;memset(py,0,sizeof(py));for (i=1;i<=n;i++)scanf("%d%d",&white[i].x,&white[i].y);for (i=1;i<=n;i++)scanf("%d%d",&black[i].x,&black[i].y);for (i=1;i<=n;i++)for (j=1;j<=n;j++) {w[i][j]=-dis(i,j);if (px[i]<w[i][j])px[i]=w[i][j];}KM();for (i=1;i<=n;i++)printf("%d\n",fa[i]);} }
转载于:https://www.cnblogs.com/handsomeJian/p/3575536.html
poj 3565 uva 1411 Ants KM算法求最小权相关推荐
- 利用Kuhn-Munkras算法求最小权值匹配
本文参考博客: http://blog.csdn.net/zhangpinghao/article/details/12242823(代码参考该博客) http://philoscience.itey ...
- UVA 1411 - Ants(二分图完美匹配)
UVA 1411 - Ants 题目链接 题意:给定一些黑点白点,要求一个黑点连接一个白点,而且全部线段都不相交 思路:二分图完美匹配,权值存负的欧几里得距离,这种话,相交肯定比不相交权值小,所以做一 ...
- 小A与欧拉路 (树加边求最小权值欧拉路+树的直径)
链接:https://ac.nowcoder.com/acm/contest/369/C 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言2621 ...
- Ants UVA - 1411(km板题竟然让我换了个板子)
题意: 给出n个白点和n个黑点的坐标,要求用n条不相交的线段把它们连接起来,其中每条线段恰好连接一个白点和一个黑点,每个点恰好连接到一条线段 解析: 带入负的欧几里得距离求就好了 假设a1-b1 与 ...
- poj 3686 The Windy's( KM算法 )
恩 , 题是好题 , 一道经典KM算法题 , 只是刚开始读错题了,感觉思路没错但就是过不了样例,受不了了就上网查了一下题意,果然题意理解错了 ,改了一下输入,又加了个标记数组就这样的过了~ 唉,由此 ...
- prim求最短路径C语言,[图论]Prim算法求最小支撑树和最短路径
这个是以前所学,现在总结成博文一篇. 对于图论中的求解最小支撑树问题和最短路径问题都有比较经典的算法,比如最小支撑树可以采用"破圈法",求解最短路径可以用"Dijkstr ...
- POJ 3255(迪杰斯特拉算法求次短路)
POJ3255,问题是求节点1到n的次短路. 在dijkstra求最短路算法的基础上进行变形,用两个数组分别记录源点到各节点最短路径和次短路径: 每次更新时,都将最短路的节点及可能成为次短路的节点pu ...
- 旋转卡壳算法求最小外接矩形代码
旋转卡壳原理:旋转卡壳详解_大学要有梦想的博客-CSDN博客_旋转卡壳 思路: 1.选择卡壳算法用于求凸多边形的最小外接矩形 1.多边形最小的外接矩形一定是以多边形的的一条边为底的一部分 2.通过这条 ...
- KM算法 最优匹配(最大权匹配) hdu 2255 奔小康赚大钱 最小权匹配 poj 2195 Going Home
最大权二分匹配问题就是给二分图的每条边一个权值,选择若干不相交的边,得到的总权值最大.解决这个问题可以用KM算法.理解KM算法需要首先理解"可行顶标"的概念.可行顶标是指关于二分图 ...
最新文章
- C/C++-标准输入/输出重定向为文件输入/输出
- iphone android 开发指南 http://mobile.tutsplus.com
- 循环控制_continue语句
- 动态规划训练9 [Brackets POJ - 2955 ]
- 深度:抖音本地生活服务的真相
- 「工具」PWA Manifest图标及 favicon.ico 生成工具
- xwork-2.1.2.jar与xwork-core-2.1.6.jar的区别是什么? 在线等待 先谢谢了
- AJAX实现导航式多条件搜索
- 苹果id注册邮箱方法
- MATLAB机器人工具箱的下载与安装
- windows - Hook技术介绍
- android启用hdcp_如何在Google Android模拟器中启用Android Market
- KEGG Orthology 数据库简介
- 12306 验证码验证流程
- 第八周助教工作总结——NWNU李泓毅
- github官网老是打不开
- Network (哈工大网课笔记)
- 机器学习相关资料推荐 http://blog.csdn.net/jiandanjinxin/article/details/51130271
- 六十二、基础框架(二十)集合物件
- java基础(含JUC):论后端工程师的个人修为