题意:

一个平面上有n个黑色的点,n个白色的点,要求黑色的点与白色点之间一一配对,且线段之间不相交。

思路:

线段不相交并不好处理,想了很久想不出,所以看了蓝书的讲解。

一个很明显的结论是,不相交的线段一定比相交的线段短,如图:一个较为直观的例子。

由于点之间一一对应,所以肯定用二分图匹配,然后要使得所有线段之和最短,那么就是求一个带权最小匹配,上KM算法解决。

把所有的边权取负值,求最大匹配即可。

代码:

 #include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std; const int N = ; double mp[N][N]; struct node
{
double x,y;
node(double a,double b)
{
x = a;
y = b;
}
}; vector<node> nx,ny; bool vis_x[N],vis_y[N];
int match[N];
double lx[N],ly[N];
double slack[N];
int ma[N]; double cal(int i,int j)
{
double dx = pow(nx[i].x - ny[j].x,);
double dy = pow(nx[i].y - ny[j].y,); return sqrt(dx + dy);
} bool dfs(int u,int n)
{
vis_x[u] = ; for (int i = ;i < n;i++)
{
if (vis_y[i]) continue; double gap = lx[u] + ly[i] - mp[u][i]; //getchar(); //printf("%.6f %.6f %.6f %.6f\n",lx[u],ly[i],mp[u][i],gap); if (fabs(gap) < 1e-)
{
vis_y[i] = ; if (match[i] == - || dfs(match[i],n))
{
match[i] = u;
return true;
}
}
else
{
slack[i] = min(slack[i],gap);
}
} return false;
} void km(int n)
{
memset(ly,,sizeof(ly));
memset(match,-,sizeof(match)); for (int i = ;i < n;i++)
{
lx[i] = mp[i][]; for (int j = ;j < n;j++)
{
lx[i] = max(lx[i],mp[i][j]);
}
} for (int i = ;i < n;i++)
{
for (int j = ;j < n;j++) slack[j] = 1e15;
//printf("gg");
while ()
{
//printf("233");
memset(vis_x,,sizeof(vis_x));
memset(vis_y,,sizeof(vis_y)); if (dfs(i,n)) break; double d = 1e15; for (int j = ;j < n;j++)
{
if (!vis_y[j]) d = min(slack[j],d);
} for (int j = ;j < n;j++)
{
if (vis_x[j]) lx[j] -= d; if (vis_y[j]) ly[j] += d;
} //getchar(); //printf("%.6f **\n",d);
}
}
} int main()
{
int n;
int kase = ; while (scanf("%d",&n) != EOF)
{
if (kase++) printf("\n"); nx.clear();
ny.clear(); for (int i = ;i < n;i++)
{
double x,y;
scanf("%lf%lf",&x,&y); nx.push_back(node(x,y));
} for (int i = ;i < n;i++)
{
double x,y;
scanf("%lf%lf",&x,&y); ny.push_back(node(x,y));
} for (int i = ;i < n;i++)
{
for (int j = ;j < n;j++)
{
mp[i][j] = -cal(i,j);
}
} km(n); for (int i = ;i < n;i++)
{
int a = i + ,b = match[i] + ;
ma[b] = a;
} for (int i = ;i < n;i++)
{
printf("%d\n",ma[i+]);
}
} return ;
}

uva 1411 Ants的更多相关文章

  1. UVA 1411 - Ants(二分图完美匹配)

    UVA 1411 - Ants 题目链接 题意:给定一些黑点白点,要求一个黑点连接一个白点,而且全部线段都不相交 思路:二分图完美匹配,权值存负的欧几里得距离,这种话,相交肯定比不相交权值小,所以做一 ...

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

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

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

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

  4. 【uva 1411 Ants蚂蚁们】

    题目大意: ·给你一个n,表示输入n个白点和n个黑点(输入每一个点的坐标).现在需要将各个白点和各个黑点一一用线段连接起来,需要满足这些线段不能够相交. ·特色: 我们如何保证线段间不相交. ·分析: ...

  5. UVa 1411 Ants(分治)

    https://vjudge.net/problem/UVA-1411 题意:n只蚂蚁和n颗苹果树,一一配对并且不能交叉. 思路:这就是巨人与鬼的问题.用分治法就行了. #include<ios ...

  6. 【UVA 1411】 Ants (KM)

    Young naturalist Bill studies ants in school. His ants feed onplant-louses that live on apple trees. ...

  7. UVA 10714 Ants 蚂蚁 贪心+模拟 水题

    题意:蚂蚁在木棍上爬,速度1cm/s,给出木棍长度和每只蚂蚁的位置,问蚂蚁全部下木棍的最长时间和最短时间. 模拟一下,发现其实灰常水的贪心... 不能直接求最大和最小的= =.只要求出每只蚂蚁都走长路 ...

  8. Ants UVA - 1411(km板题竟然让我换了个板子)

    题意: 给出n个白点和n个黑点的坐标,要求用n条不相交的线段把它们连接起来,其中每条线段恰好连接一个白点和一个黑点,每个点恰好连接到一条线段 解析: 带入负的欧几里得距离求就好了 假设a1-b1 与 ...

  9. uva 10714 Ants(贪心)

    题目连接:10714 - Ants 题目大意:一根棍子上有n只蚂蚁, 这些蚂蚁开始可以任意朝着一个方向移动一直走,向左或是向右,并且移动速度是相同的,但是一旦蚂蚁碰到迎面走来的另一只蚂蚁,那么这两只蚂 ...

随机推荐

  1. 误删 /user/bin目录后的补救

    当危险的动作发生, 误删 /user/bin目录后的补救 以下是昨天晚上真实的误操作现场,模拟记录一下 (这是测试环境,所以操作得很随意,有些执行动作很不规范) 在上面编译一个软件Dboop,完事以后 ...

  2. Runtime源码解析(JDK1.8)

    package java.lang; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import java.io ...

  3. HTML定位简介

    转载出处 定位一直是WEB标准应用中的难点,如果理不清楚定位那么可能应实现的效果实现不了,实现了的效果可能会走样.如果理清了定位的原理,那定位会让网页实现的更加完美. 定位的定义:在CSS中关于定位的 ...

  4. Spring Boot应用的后台运行配置

    酱油一篇,整理一下关于Spring Boot后台运行的一些配置方式.在介绍后台运行配置之前,我们先回顾一下Spring Boot应用的几种运行方式: 运行Spring Boot的应用主类 使用Mave ...

  5. python基础学习笔记二之列表

    1.列表 ①列表的创建: ②列表的查询(索引): ③列表的切片操作: 此处要注意到:返回索引0到3的元素,顾头不顾尾. ④列表的增加: s.append()  #直接在结尾追加 s.insert()  ...

  6. DB2开发系列之三——SQL函数

    1.内置函数分类(SYSIBM模式内) 1)标量函数:返回一个标量值的函数: 2)聚合函数:也叫列函数,也返回一个标量值,这个值是一组输入值的计算结果:3)表函数:向引用它的 SQL 语句返回一个表: ...

  7. JSON解析的几种方式

    在开发中,网络请求和json解析使用的频率是一样高的,因为网络请求返回来的一般都是json(当然还有xml),这里讨论的是json,网络请求的工具类前面我的博客已经写过了,这里给出网址:http:// ...

  8. [poj3107]Godfather_树形dp_树的重心

    Godfather poj-3107 题目大意:求树的重心裸题. 注释:n<=50000. 想法:我们尝试用树形dp求树的重心,关于树的重心的定义在题目中给的很明确.关于这道题,我们邻接矩阵存不 ...

  9. kvm之十二:虚拟机迁移

    虚拟机迁移该方式要确保虚拟机是关机状态.virsh shutdown snalevirsh dumpxml snale > /etc/libvirt/qemu/snale_qy.xml  // ...

  10. pl/sql进阶--例外处理

    在pl/sql的执行过程中发生异常时系统所作的处理称为一个例外情况(exception).通常例外情况的种类有三种: 1.预定义的oracle例外情况oracle预定义的例外情况大约有24个,对于这种 ...