题意:n只蚂蚁,n棵树,每只蚂蚁要连一棵树,连线(直线)不能相交,给出n只蚂蚁和n棵树的坐标,输出n只蚂蚁所配对的树的编号(1 <= n <= 100, -10000 <= 坐标x, y <= 10000)。

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2044

——>>二分图最佳完美匹配第一题,挺简单,也挺容易写错。

很明显,蚂蚁为一个顶点集,树为一个顶点集,如果从蚂蚁向树匹配,那么最后输出前要先做一次o(n)的映射,如果从树向蚂蚁匹配,则最后可直接输出。

建图:以n棵树为X点,以n只蚂蚁为Y点,权值w[i][j]为树i到蚂蚁j的距离的相反数(二分图最佳完美匹配求的是权和最大,而我们要的是权和最小(这样就不会有线段相交),所以权值取了相反数后变成了求二分图的最大完美匹配),跑一次KM就好。

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. const int maxn = 100 + 10;
  8. const double eps = 1e-10;
  9.  
  10. int n, fa[maxn];
  11. double w[maxn][maxn], Lx[maxn], Ly[maxn];
  12. bool S[maxn], T[maxn];
  13.  
  14. struct Point{
  15. double x, y;
  16. Point(double x = 0, double y = 0):x(x), y(y){}
  17. };
  18.  
  19. Point ant[maxn], tree[maxn];
  20.  
  21. double Dis(Point A, Point B){
  22. return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y));
  23. }
  24.  
  25. bool match(int i){
  26. S[i] = 1;
  27. for(int j = 1; j <= n; j++) if(fabs(Lx[i]+Ly[j]-w[i][j]) < eps && !T[j]){
  28. T[j] = 1;
  29. if(!fa[j] || match(fa[j])){
  30. fa[j] = i;
  31. return 1;
  32. }
  33. }
  34. return 0;
  35. }
  36.  
  37. void update(){
  38. double a = 1 << 30;
  39. for(int i = 1; i <= n; i++) if(S[i])
  40. for(int j = 1; j <= n; j++) if(!T[j])
  41. a = min(a, Lx[i]+Ly[j]-w[i][j]);
  42. for(int i = 1; i <= n; i++){
  43. if(S[i]) Lx[i] -= a;
  44. if(T[i]) Ly[i] += a;
  45. }
  46. }
  47.  
  48. void KM(){
  49. for(int i = 1; i <= n; i++) fa[i] = Lx[i] = Ly[i] = 0;
  50. for(int i = 1; i <= n; i++){
  51. while(1){
  52. for(int j = 1; j <= n; j++) S[j] = T[j] = 0;
  53. if(match(i)) break;
  54. else update();
  55. }
  56. }
  57. }
  58.  
  59. int main()
  60. {
  61. int first = 1;
  62. while(scanf("%d", &n) == 1){
  63. for(int i = 1; i <= n; i++) scanf("%lf%lf", &ant[i].x, &ant[i].y);
  64. for(int i = 1; i <= n; i++) scanf("%lf%lf", &tree[i].x, &tree[i].y);
  65. for(int i = 1; i <= n; i++)
  66. for(int j = 1; j <= n; j++)
  67. w[i][j] = -Dis(tree[i], ant[j]); //计算树i与蚂蚁j的距离,并用其相反数作权值
  68. KM();
  69. if(first) first = 0;
  70. else puts("");
  71. for(int i = 1; i <= n; i++) printf("%d\n", fa[i]);
  72. }
  73. return 0;
  74. }

LA - 4043 - Ants的更多相关文章

  1. UVALive 4043 Ants

    KM   构图求最小权值匹配 保证最小的权值,所连的边一定是能够不相交的. Ants Time Limit: 3000MS   Memory Limit: Unknown   64bit IO For ...

  2. UVALive 4043 Ants 蚂蚁(二分图最佳完美匹配,KM算法)

    题意: 有n个蚂蚁n棵树,蚂蚁与树要配对,在配对成功的一对之间连一条线段,要求所有线段不能相交.按顺序输出蚂蚁所匹配的树. 思路: 这个题目真是技巧啊,不能用贪心来为每个蚂蚁选择最近的树,这样很可能是 ...

  3. UVALive 4043 Ants(二分图完美匹配)

    题意:每个蚁群有自己的食物源(苹果树),已知蚂蚁靠气味辨别行进方向,所以蚁群之间的行动轨迹不能重叠.现在给出坐标系中n个蚁群和n棵果树的坐标,两两配对,实现以上要求.输出的第 i 行表示第 i 个蚁群 ...

  4. UVaLive 4043 Ants (最佳完美匹配)

    题意:给定 n 个只蚂蚁和 n 棵树的坐标,问怎么匹配使得每个蚂蚁到树的连线不相交. 析:可以把蚂蚁和树分别看成是两类,那么就是一个完全匹配就好,但是要他们的连线不相交,那么就得考虑,最佳完美匹配是可 ...

  5. LA 4043 最优匹配

    题目链接:https://vjudge.net/contest/161820#problem/A 题意: n 个 白点,n 个黑点,给出了坐标,求完美匹配后,各点不相交,输出白点对于的黑点编号:(输出 ...

  6. Uvalive 4043 Ants —— 二分图最大权匹配 KM算法

    题目链接:https://vjudge.net/problem/UVALive-4043 题意: 给出n个白点和n个黑点的坐标, 要求用n条不相交的线段把他们连接起来,其中每条线段恰好连接一个白点和黑 ...

  7. 【POJ3565】ANTS KM算法

    [POJ3565]ANTS 题意:平面上有2*n个点,N白N黑.为每个白点找一个黑点与之连边,最后所有边不交叉.求一种方案. 题解:KM算法真是一个神奇的算法,虽然感觉KM能做的题用费用流都能做~ 本 ...

  8. 训练指南 UVALive - 4043(二分图匹配 + KM算法)

    layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...

  9. POJ3565 Ants 和 POJ2195 Going Home

    Ants Language:Default Ants Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7975 Accepted: ...

随机推荐

  1. [置顶] 图书推荐:SQL Server 2012 T-SQL基础 Itzik Ben-Gan

    经过近三个月的不懈努力,终于翻译完毕了.图书虽然是基础知识,但是,即使你已经使用T-SQL几年,很多地方还是能够弥补你的知识空白.大师级的人物写基础知识,或许你想知道这基础中还有哪些深奥,敬请期待吧. ...

  2. ExecuteReader: CommandText 属性尚未初始化

    没有对sqlcommand对象的commandtext属性赋值说白了就是没写SQL语句 -.- 无语死了.

  3. GCD基本使用

    主要概念 队列 dispatch_queue_t,队列名称在调试时辅助,无论什么队列和任务,线程的创建和回收不需要程序员操作,有队列负责. 串行队列:队列中的任务只会顺序执行(类似跑步) dispat ...

  4. Qt 释放新建窗口资源

    当Widget *w = new Widget(); 不方便调用 delete w;时 Widget *w = new Widget(); w->setAttribute(Qt::WA_Dele ...

  5. svn回滚版本2

    svn 版本回滚 取消对代码的修改分为两种情况:   第一种情况:改动没有被提交(commit). 这种情况下,使用svn revert就能取消之前的修改. svn revert用法如下: # svn ...

  6. 利用Java内置的API开发JMX功能

    一.什么是JMX JMS是一种Java规范,定义了如何管理一个软件系统(或应用程序)的规范. 对于一个简单的应用程序,该程序本身不需要被管理.但如果是开发的一个复杂系统(如一个电商平台.一个企业内部管 ...

  7. GPSR协议移植

    修改的文件有packet.h.cmu-trace.cc.priqueue.cc.ns-packet.tcl.Makefile 1.在 $HOME/ns-allinone-2.29/ns-2.29下新建 ...

  8. 分析内存使用情况 (JavaScript)

    [此文档是初定版,随时可能进行更改.] JavaScript 内存分析器在 Visual Studio 2012 更新 1 和 Visual Studio 2013 中提供,旨在帮助你了解内存使用量和 ...

  9. [置顶] 自娱自乐7之Linux UDC驱动2(自编udc驱动,现完成枚举过程,从驱动代码分析枚举过程)

    花了半个月,才搞定驱动中的枚举部分,现在说linux的枚举,windows可能有差别. 代码我会贴在后面,现在只是实现枚举,你可能对代码不感兴趣,我就不分析代码了,你可以看看 在<自娱自乐1&g ...

  10. perl 为什么要用引用来做对象呢?

    perl 为什么要用引用来做对象呢? 因为一个重要的原因是 my 引用 脱离作用域,外部仍旧生效