博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ-3565 Ants 空间点对不相交匹配-最小权值匹配
阅读量:7053 次
发布时间:2019-06-28

本文共 1929 字,大约阅读时间需要 6 分钟。

题意:给定平面上两类同样多的点,要求输出一种方案使得所有匹配的点的连线两两不相交。

解法:考虑到下面的一般情况:

可以很容易的证明两条交叉边的距离和一定大于两条不交叉的距离和,因此问题转化为只要原图中存在交叉边,那么就可以找到更小的匹配的方式使得总距离更小。使用KM算法求出最小权值匹配输出匹配方案即可。

代码如下:

#include 
#include
#include
#include
#include
#include
using namespace std;int N;double w[105][105];int sx[105], sy[105];double lx[105], ly[105];double slack[105];int match[105];struct Node { int x, y; }c[105], t[105];double dist(const Node &a, const Node &b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}void build() { for (int i = 1; i <= N; ++i) { for (int j = 1; j <= N; ++j) { w[i][j] = -dist(c[i], t[j]); } }}int path(int u) { sx[u] = 1; for (int i = 1; i <= N; ++i) { if (sy[i]) continue; double t = lx[u] + ly[i] - w[u][i]; if (fabs(t) < 1e-6) { // 如果这个值等于0 sy[i] = 1; if (!match[i] || path(match[i])) { match[i] = u; return true; } } else { slack[i] = min(slack[i], t); } } return false;}void KM() { memset(match, 0, sizeof (match)); fill(ly, ly+105, 0); fill(lx, lx+105, 0); for (int i = 1; i <= N; ++i) { for (int j = 1; j <= N; ++j) { // 为i选择一个最大的权值 lx[i] = max(lx[i], w[i][j]); } } for (int i = 1; i <= N; ++i) { // 每一次都要为i找到一条增广路 fill(slack, slack+105, 1e30); while (1) { memset(sx, 0, sizeof (sx)); memset(sy, 0, sizeof (sy)); if (path(i)) break; double d = 1e30; for (int j = 1; j <= N; ++j) { if (!sy[j]) d = min(d, slack[j]); } for (int j = 1; j <= N; ++j) { if (sx[j]) lx[j] -= d; if (sy[j]) ly[j] += d; else slack[j] -= d; } } } for (int i = 1; i <= N; ++i) { for (int j = 1; j <= N; ++j) { if (match[j] == i) { printf("%d\n", j); break; } } }}int main() { while (scanf("%d", &N) != EOF) { for (int i = 1; i <= N; ++i) { scanf("%d %d", &c[i].x, &c[i].y); } for (int i = 1; i <= N; ++i) { scanf("%d %d", &t[i].x, &t[i].y); } build(); KM(); } return 0; }

 

转载于:https://www.cnblogs.com/Lyush/archive/2013/04/16/3024244.html

你可能感兴趣的文章
团队项目冲刺5
查看>>
poj3254 Corn Fields(状压dp)
查看>>
方便记忆的电话号码
查看>>
+CIMG+彩色图片边缘提取实验记录_canny/hough transfrom
查看>>
BZOJ2179:FFT快速傅立叶(FFT)
查看>>
mysql常用命令总结
查看>>
C# Azure-让http自动跳转到https链接
查看>>
寻找符合条件的整数
查看>>
一:依使初衷
查看>>
Linux设备驱动之USB
查看>>
Active Desktop--桌面字体背景被修改
查看>>
网页中自动获取访问用户所在城市的接口插件
查看>>
锋利jquery第三章案例 总结
查看>>
Cocos Creator Animation 组件
查看>>
RH033读书笔记(1)-Lab2 Linux Usage Basics
查看>>
window对象 (浏览器对象模型)
查看>>
Loadrunner 关于参数赋值取值的操作
查看>>
C# 实现保留两位小数的方法
查看>>
Http协议4个新的http状态码:428、429、431、511;
查看>>
C#类型简述
查看>>