poj3565 ants(KM)
来源:互联网 发布:电磁炮 激光炮 知乎 编辑:程序博客网 时间:2024/05/17 06:14
题目链接:http://poj.org/problem?id=3565
题意: 有 N 个蚂蚁,N 个苹果,要在每个蚂蚁和一个相应的苹果之间连边,问如何给蚂蚁分配苹果,可以使这些边不相交。
分析:
应为在最小权值匹配的情况下满足没有边相交,可以简单证明,假设最小完备匹配中有两条线段AC和BD相交于点E,此时我们可以不连接AC和BD而去连接AD和BC,由于AE+DE>AD和BE+CE>BC,所有我们可以得出新连接的边的权值和一定比原来的边的权值和小,这样就可以得到一种权值和更小的匹配,这原来的匹配是最小带权和的匹配矛盾, 因此最小带权和的匹配中不会出现有两条线段相交的情况。KM算法是求最大权匹配问题,因此将此处的权值取距离的相反数即可。
源代码:
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const double INF=9999999999.0;const double eps=1e-5;struct Node{ double x,y;} ant[110],apple[110];double dis(Node a,Node b){ return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}int nx,ny;bool visx[110],visy[110];int linker[110];double lx[110],ly[110];double slack[110];double mp[110][110];bool dfs(int x){ visx[x]=true; for(int y=1; y<=ny; y++) { if(visy[y]) continue; double tmp=lx[x]+ly[y]-mp[x][y]; if(fabs(tmp)<eps) { visy[y]=true; if(linker[y]==-1 || dfs(linker[y])) { linker[y]=x; return true; } } else if(slack[y]>tmp) slack[y]=tmp; } return false;}void KM(){ memset(linker,-1,sizeof linker); memset(ly,0,sizeof ly); for(int i=1; i<=nx; i++) { lx[i]=-INF; for(int j=1; j<=ny; j++) if(mp[i][j]>lx[i]) lx[i]=mp[i][j]; } for(int x=1; x<=nx; x++) { for(int i=1; i<=ny; i++) slack[i]=INF; while(1) { memset(visx,0,sizeof visx); memset(visy,0,sizeof visy); if(dfs(x)) break; double d=INF; for(int i=1; i<=ny; i++) if(!visy[i] && d>slack[i]) d=slack[i]; for(int i=1; i<=nx; i++) if(visx[i]) lx[i]-=d; for(int i=1; i<=ny; i++) { if(visy[i]) ly[i]+=d; else slack[i]-=d; } } }}int main(){ int n; while(scanf("%d",&n)!=EOF) { for(int i=1; i<=n; i++) { scanf("%lf%lf",&ant[i].x,&ant[i].y); } for(int i=1; i<=n; i++) { scanf("%lf%lf",&apple[i].x,&apple[i].y); } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { mp[i][j]=-dis(apple[i],ant[j]); } } nx=ny=n; KM(); for(int i=1;i<=ny;i++) printf("%d\n",linker[i]); } return 0;}
0 0
- poj3565 ants(KM)
- poj3565 Ants(KM)
- 【KM】POJ3565[Ants]题解
- poj3565 Ants
- POJ3565-Ants
- poj3565 Ants
- poj3565 ants
- poj3565-Ants
- POJ3565 Ants
- poj3565(KM)
- poj3565 Ants(训练手册例题翻译)
- KM算法(3)poj3565
- POJ 3565 Ants (KM)
- km算法+slack优化 poj3565
- hdu2255+poj3565(km模板题)
- POJ 3565 Ants(计算几何,KM)
- poj 3565 Ants (KM算法)
- POJ3565 Ants【二分图最佳匹配】
- 栈的基本操作
- Hive-0.12.0的安装及简单使用
- Codeforces Round #365 (Div. 2) [D] Mishka and Interesting sum
- jeecg操作子标签点击弹出对话框(dialog)以及消息框弹出
- 题目:在二叉树中给出两个已知结点,求这两个结点的最低公共祖先
- poj3565 ants(KM)
- shell脚本读取配置文件
- 在Fragment中使用Listview
- Google 最常用的搜索指令
- light oj 1258
- 注册了pangu.im,盘古,vigor.im,crystal.im, jade.im, fool.im,很好的后缀啊im我是的意思
- IE8和Firefox对于table有不同的展示效果
- 程序员书单
- 第二层、三层、四层交换机原理