题目链接:点击查看

题目大意:给出n个蚂蚁和n个苹果树的坐标,我们需要求出每个蚂蚁平时觅食所要去的苹果树,必须保证所有路径不能有交叉

题目分析:因为所有的边不能有交叉,所以我们选择距离最短的两个点匹配即可,然后n个蚂蚁匹配n个苹果树,又是一个完备匹配问题,那么这个题目就转换成了一个最小权匹配的问题了,直接套模板就行了吗?不,其实还有个很严谨的证明,一开始我是为了省精度,用了距离的平方建边,一直WA,后来改成double类型的距离建边,也就是开了个sqrt然后就A了,一直想不明白为什么,看了大佬的证明后就突然有点小理解了:

这道题能用KM在于四边形不等式的几何形式dist (A,B)+dist(C,D)>dist(A,C)+dist(B,D),其中ABCD是四边形,证明利用对角线交点O与AB,CD两条边构成的三角形不等式证明,即OA+OB>AB,OC+OD>CD,两式相加得到AC+BD>AB+CD,对于平方,没有三角形不等式,事实上可以构造使AB*AB+CD*CD=AC*AC+BD*BD

大概就是这样,求边权的时候需要用实际距离,然后因为涉及到了double类型,就要开一个eps保持精度,1e-6足够

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const double inf=1e10;const double eps=1e-6;const int N=110;int n;struct Pos
{int x,y;
}ant[N],tree[N];double dis(Pos& a,Pos& b)
{return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}double la[N],lb[N];//顶标bool visa[N],visb[N];//访问标记double maze[N][N];//边权int match[N];//右部点匹配了哪一个左部点double upd[N];bool dfs(int x)
{visa[x]=true;//访问标记:x在交错树中for(int i=1;i<=n;i++){if(!visb[i]){if(la[x]+lb[i]-maze[x][i]<eps)//相等子图{visb[i]=true;//访问标记:y在交错树中if(!match[i]||dfs(match[i])){match[i]=x;return true;}}elseupd[i]=min(upd[i],la[x]+lb[i]-maze[x][i]);}}return false;
} int KM()
{memset(match,0,sizeof(match));for(int i=1;i<=n;i++){la[i]=-inf;lb[i]=0;for(int j=1;j<=n;j++)la[i]=max(la[i],maze[i][j]);}for(int i=1;i<=n;i++){while(1)//直到左部点找到匹配{memset(visa,false,sizeof(visa));memset(visb,false,sizeof(visb));for(int i=1;i<=n;i++)upd[i]=inf;if(dfs(i))break;double delta=inf;for(int j=1;j<=n;j++)if(!visb[j])delta=min(delta,upd[j]);for(int j=1;j<=n;j++)//修改顶标{if(visa[j])la[j]-=delta;if(visb[j])lb[j]+=delta;}}}int ans=0;for(int i=1;i<=n;i++)ans+=maze[match[i]][i];return ans;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)scanf("%d%d",&ant[i].x,&ant[i].y);for(int i=1;i<=n;i++)scanf("%d%d",&tree[i].x,&tree[i].y);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)maze[i][j]=-dis(tree[i],ant[j]);KM();for(int i=1;i<=n;i++)printf("%d\n",match[i]);} return 0;
}

POJ - 3565 Ants(二分图最小权匹配+KM+思维)相关推荐

  1. POJ - 2195 Going Home(二分图最小权匹配+KM+思维建边/最小费用最大流)

    题目链接:点击查看 题目大意:给出一个n*m的地图,现在有一定数量的小人要回到屋子里去,题目保证图中的小人和屋子的数量是一致的,小人回到小屋的距离是两个点坐标的曼哈顿距离,每个小屋只能容纳一个小人,现 ...

  2. HDU - 3488 Tour(二分图最小权匹配+KM)

    题目链接:点击查看 题目大意:给出n个城市,再给出m条有向的道路,问若想以一个或多个环的形式遍历所有的城市一次,所需要的最小权值是多少 题目分析:刚拿到这个题目是有点懵的,因为不知道题目让求什么,其实 ...

  3. UVALive 3353 - Optimal Bus Route Design(二分图最小权匹配)

    题目链接 https://cn.vjudge.net/problem/UVALive-3353 [题意] 给你n个点(n<=100)的有向带权图,你要找到n个有向环,使得每个点恰好属于一个环,要 ...

  4. 牛客多校10 - Identical Trees(dp+二分图最小权匹配)

    题目链接:点击查看 题目大意:给出两个同构树 tree1 和 tree2 ,问最少需要改变多少个结点的标号,可以使得这两棵树相同 题目分析:直接 dfs 维护 dp 就好了,dp[ i ][ j ] ...

  5. HDU 1533 二分图最小权匹配 Going Home

    带权二分图匹配,把距离当做权值,因为是最小匹配,所以把距离的相反数当做权值求最大匹配. 最后再把答案取一下反即可. 1 #include <iostream> 2 #include < ...

  6. 二分图最佳匹配 KM算法 Hdu2255奔小康赚大钱 + Poj 3565 Ants

    2014-10-4 更新 在最下面增加了基于邻接表的模板 理论:http://blog.sina.com.cn/s/blog_691ce2b701016reh.html http://philosci ...

  7. KM算法 最优匹配(最大权匹配) hdu 2255 奔小康赚大钱 最小权匹配 poj 2195 Going Home

    最大权二分匹配问题就是给二分图的每条边一个权值,选择若干不相交的边,得到的总权值最大.解决这个问题可以用KM算法.理解KM算法需要首先理解"可行顶标"的概念.可行顶标是指关于二分图 ...

  8. pku 2195 Going Home KM最小权匹配问题

    http://poj.org/problem?id=2195 在一个n*m的方格里有nx人(m)和ny个房子(H),(nx = ny)人每次可以向四周移动单位距离,花费1¥,求最小花费是每个人都能进入 ...

  9. pku The Windy's KM最小权匹配 or 最小费用最大流

    http://poj.org/problem?id=3686 题意: 给定n个玩具,有m个车间,给出每个玩具在每个车间的加工所需的时间mat[i][j]表示第i个玩具在第j个车间加工所需的时间,规顶只 ...

最新文章

  1. 开涛老师的博客汇总 -- Web MVC 开发学习
  2. 03构建之法阅读笔记之三
  3. 1095 Cars on Campus (30 分)【难 / 模拟 未完成】
  4. python和revit_如何在Python中产生新的RevitAPI对象
  5. 利用canvas来绘制一个会动的图画
  6. 所有controller interceptor_filter、interceptor、aspect不知如何选择
  7. 数据结构与算法笔记(二) 线性表(数组描述)
  8. Python实现获取IP代码
  9. php和mysql做甘特图_Twproject Gantt开源甘特图功能扩展
  10. vb mysql登录界面_VB\数据库--模拟系统登录界面
  11. DIY一个正弦表计算器,用于单片机查表生成正弦波
  12. 国科大学习资料--形式语言与自动机理论(姚刚)-2020期末考试题
  13. 计算机图形学-油画家算法
  14. Cadence OrCAD Capture 打印图纸的某一个部分的方法
  15. 8583协议报文例子。
  16. 安卓 类微信界面实现
  17. LibreCAD使用记录
  18. QR分解的三种实现方法
  19. 18周过后~(学期总结)
  20. 向量复习(一):定义、求解、四则运算、点积和叉积

热门文章

  1. 搭建K8s集群(kubeadm方式)-部署master节点
  2. kubernetes-Pod结构
  3. zookeeper的名词复盘-集群角色
  4. zookeeper的设计猜想-防止单点故障
  5. http协议的完整组成
  6. 搭建项目前端页面环境
  7. http响应协议分析
  8. PageHelper概述与基本使用步骤介绍
  9. 返回index.html页面
  10. 消息队列入门案例-环境搭建