题目大意:

·给你一个n,表示输入n个白点和n个黑点(输入每一个点的坐标)。现在需要将各个白点和各个黑点一一用线段连接起来,需要满足这些线段不能够相交。

·特色:

我们如何保证线段间不相交。

·分析:

由“黑白”可以想到用二分图匹配(最大流问题亦可)。用到一个神秘结论,可以巧妙地将“相交”和“不相交”转化为具体数值大小关系,进而转化为权值。结论为:【四边形两条对角线的和必定大于它任何一组对边的和】

用一下这幅图进行分析:

         

下面来比较线段交叉和不交叉情况下,两条线段和的大小:

①交叉线段:(蓝色线段)

D1=dis(A,C)+dis(B,D)

    =(a2-a1)2+Y2+(b2-b1)2+X2

②非交叉线段(这里计算AB,CD,其余情况可以用对称性等价得到)

D2=dis(A,B)+dis(C,D)

     =a12+b12+(X-a2)2+(Y-b2)2

【作差】:

D1-D2=dis(A,C)+dis(B,D)-dis(A,B)-dis(C,D)

           =2*b2(Y-b1)+2*a2(X-a1)

【结论】:

由于Y==b1与X==a1同时满足是不可能的(点重合了!)

又因为Y>=b1,X>=a1所以上面D1-D2的式子必为正数。

这意味着D1恒大于D2。因此这需要我们进行最小权值的二分图完全匹配。

 1 #include<stdio.h>
2 #include<algorithm>
3 #include<cstring>
4 #include<cmath>
5 #define go(i,a,b) for(int i=a;i<=b;i++)
6 #define fo(i,a,x) for(int i=a[x],v=e[i].v;i>-1;i=e[i].next,v=e[i].v)
7 #define mem(a,b) memset(a,b,sizeof(a))
8 #define inf 200000000
9 #define eps 0.000001
10 using namespace std;const int N=1003
;
11 struct POS{double
x,y;}white[N],black[N];
12 struct E{int v,next;double w;}e[N*
N];
13 int
n,head[N],k,c[N],S[N],T[N];
14 void ADD(int u,int v,double w){e[k]=(E){v,head[u],w};head[u]=k++
;}
15 double A(double x){return x*x;};double
slack[N],Lx[N],Ly[N];
16 double dis(POS a,POS b){return sqrt(A(a.x-b.x)+A(a.y-
b.y));}
17 bool aug(int
u){
18 S[u]=1;fo(i,head,u)if(!
T[v])
19 {double t=Lx[u]+Ly[v]-e[i].w;if(t<eps&&t>-
eps)
20 {T[v]=1;if(!c[v]||aug(c[v])){c[v]=u;return 1
;}}
21 else slack[v]=min(slack[v],t);}return 0
;
22
}
23 void revise(){double a=
inf;
24 go(i,1,n)if(!T[i])a=
min(a,slack[i]);
25 go(i,1,n)S[i]?Lx[i]-=a,1:1,T[i]?Ly[i]+=a,1:1
;
26
}
27 int main(){while(~scanf("%d",&
n)){
28 mem(head,-1);k=0
;
29 go(i,1,n)scanf("%lf%lf",&white[i].x,&
white[i].y);
30 go(i,1,n)scanf("%lf%lf",&black[i].x,&
black[i].y);
31 go(i,1,n)go(j,1,n)ADD(i,j,-
dis(white[i],black[j]));
32
33 go(u,1,n){Ly[u]=c[u]=0;Lx[u]=-
inf;
34 fo(i,head,u)Lx[u]=
max(Lx[u],e[i].w);}
35
36 go(i,1,n){go(j,1,n)slack[j]=
inf;
37 for(;;){go(j,1,n)S[j]=T[j]=0
;
38 if(aug(i))break;else
revise();}}
39
40 go(i,1,n)go(j,1,n)if(c[j]==
i)
41 {printf("%d\n",j);break
;}
42 }return 0;}//Paul_Guderian

【大米饼代码】

我看见了一条河。

【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. UVA 10714 Ants 蚂蚁 贪心+模拟 水题

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

  4. UVa 1411 Ants(分治)

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

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

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

  6. uva 1411 Ants

    题意: 一个平面上有n个黑色的点,n个白色的点,要求黑色的点与白色点之间一一配对,且线段之间不相交. 思路: 线段不相交并不好处理,想了很久想不出,所以看了蓝书的讲解. 一个很明显的结论是,不相交的线 ...

  7. 【UVA 1411】 Ants (KM)

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

  8. cogs 1456. [UVa 10881,Piotr's Ants]蚂蚁

    1456. [UVa 10881,Piotr's Ants]蚂蚁 ★   输入文件:Ants.in   输出文件:Ants.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述 ...

  9. [ACM_模拟] UVA 10881 Piotr's Ants[蚂蚁移动 数组映射 排序技巧]

    "One thing is for certain: there is no stopping them;the ants will soon be here. And I, for one ...

随机推荐

  1. Ubuntu登陆密码忘记

    在VMware中安装了Ubuntu 10.04,经过了一段时间,再次登录的时候居然进不去了, 一开始不知道怎样在虚拟机中进入到Grub启动界面,网上搜索了一番,按照以下步骤重新为用户设定了新密码. 重 ...

  2. fs输出文件目录

    var http = require("http"); var fs = require("fs"); var server = http.createServ ...

  3. Java 中 compareTo方法问题

    compareTo方法原理:先读取出字符串的第一个“字母”进行比较,比较的方法是ascii码表的值(字符所对应的十进制值),如果前面的大那么返回1,后面的大返回-1:此位置相同,继续比较下一位,直到最 ...

  4. SELinux与进程管理

  5. OptaPlanner - 把example运行起来(运行并浅析Cloud balancing)

    经过上面篇长篇大论的理论之后,在开始讲解Optaplanner相关基本概念及用法之前,我们先把他们提供的示例运行起来,好先让大家看看它是如何工作的.OptaPlanner的优点不仅仅是提供详细丰富的文 ...

  6. Java NIO之选择器

    1.简介 前面的文章说了缓冲区,说了通道,本文就来说说 NIO 中另一个重要的实现,即选择器 Selector.在更早的文章中,我简述了几种 IO 模型.如果大家看过之前的文章,并动手写过代码的话.再 ...

  7. __all__

    相信很多人第一次见到这个__all__都很好奇,他有什么作用 那他到底有什么作用呢? 先上代码 from scrapy.utils.reqser import request_to_dict, req ...

  8. MySQL中使用sql语句获得表结构

    最近在研究PHP,那么就必须涉及到mysql.其中一个功能通过表数据自动生成页面,紧接着发现在一张空表中无法读取数据(因为人家刚刚新建,就是空的没有数据) 延伸出来便是直接查表结构获得字段名,再进行处 ...

  9. python--同步锁/递归锁/协程

    同步锁/递归锁/协程 1 同步锁 锁通常被用来实现对共享资源的同步访问,为每一个共享资源创建一个Lock对象,当你需需要访问该资源时,调用acquire()方法来获取锁对象(如果其他线程已经获得了该锁 ...

  10. pandas(七)数据规整化:清理、转换、合并、重塑之合并数据集

    pandas对象中的数据可以通过一些内置的方式进行合并: pandas.merge 可根据一个或多个键将不同的DataFrame中的行连接起来. pandas.concat可以沿着一条轴将多个对象堆叠 ...