【算法系列学习】Dijkstra算法变形 [kuangbin带你飞]专题四 最短路练习
2017-04-04 19:58
465 查看
https://vjudge.net/contest/66569#problem/B
类试题:noip2013 货物运输
POJ 1797 Heavy Transportation
方法一:Dijkstra变形
http://blog.csdn.net/u013446688/article/details/42777173
关键在于对松弛的变形,这里不是求源点到每个点的所有路径中的路径长度最小值,而是求源点到每个点的所有路径中Frog distance(路径中的最大距离)的最小值
所以dis[k]=min(dis[k],dis[v]+map[v][k])变成了dis[k]=min(dis[k],max(dis[v],map[v][k]))
这里的dis[k]不再是源点到结点k所有路径中路径长度的最小值,而是源点到结点k所有路径中Frog distance(路径中的最大距离)的最小值。
为了理解dis[k]=min(dis[k],max(dis[v],map[v][k])),我们可以做这样的假设:源点到v的路径有三条,这三条路径的frog distance分别是3,4,5;那么dis[v]就是3。
现在分两种情况分别进行讨论:
1.map[v][k]>dis[v],由于源点经过v到达k的路径也有三条,这三条的frog distance就分别变成了map[v][k],max(4,map[v][k]),max(5,map[v][k]);那么dis[k]就一定是最小值map[v][k].
2.map[v][k]<=dis[v],则这三条路径的frog distance 还是3,4,5.dis[k]就等于dis[v]
下面是AC的代码:
Kruskal
类试题:noip2013 货物运输
POJ 1797 Heavy Transportation
方法一:Dijkstra变形
http://blog.csdn.net/u013446688/article/details/42777173
关键在于对松弛的变形,这里不是求源点到每个点的所有路径中的路径长度最小值,而是求源点到每个点的所有路径中Frog distance(路径中的最大距离)的最小值
所以dis[k]=min(dis[k],dis[v]+map[v][k])变成了dis[k]=min(dis[k],max(dis[v],map[v][k]))
这里的dis[k]不再是源点到结点k所有路径中路径长度的最小值,而是源点到结点k所有路径中Frog distance(路径中的最大距离)的最小值。
为了理解dis[k]=min(dis[k],max(dis[v],map[v][k])),我们可以做这样的假设:源点到v的路径有三条,这三条路径的frog distance分别是3,4,5;那么dis[v]就是3。
现在分两种情况分别进行讨论:
1.map[v][k]>dis[v],由于源点经过v到达k的路径也有三条,这三条的frog distance就分别变成了map[v][k],max(4,map[v][k]),max(5,map[v][k]);那么dis[k]就一定是最小值map[v][k].
2.map[v][k]<=dis[v],则这三条路径的frog distance 还是3,4,5.dis[k]就等于dis[v]
下面是AC的代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<cmath> 7 8 using namespace std; 9 int n; 10 int cnt; 11 const int maxn=2e4+10; 12 13 14 15 struct edge 16 { 17 int x,y; 18 double w; 19 }e[maxn]; 20 struct node 21 { 22 int x; 23 int y; 24 }nd[203]; 25 double dist(const node& a,const node& b) 26 { 27 return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y)); 28 } 29 bool cmp(const edge& a,const edge& b) 30 { 31 return a.w<b.w; 32 } 33 int fa[maxn]; 34 int find(int i) 35 { 36 if(fa[i]==-1) 37 { 38 return i; 39 } 40 return fa[i]=find(fa[i]); 41 } 42 bool bind(int i,int k) 43 { 44 i=find(i); 45 k=find(k); 46 if(i!=k) 47 { 48 fa[i]=k; 49 return true; 50 } 51 return false; 52 } 53 double Kruskal() 54 { 55 for(int i=0;i<cnt;i++) 56 { 57 if(bind(e[i].x,e[i].y)) 58 { 59 if(find(1)==find(2)) 60 { 61 return e[i].w; 62 } 63 } 64 } 65 } 66 int main() 67 { 68 int kas=1; 69 while(scanf("%d",&n)&&n) 70 { 71 cnt=0; 72 for(int i=1;i<=n;i++) 73 { 74 scanf("%d%d",&nd[i].x,&nd[i].y); 75 for(int k=1;k<i;k++) 76 { 77 e[cnt].x=i; 78 e[cnt].y=k; 79 e[cnt++].w=dist(nd[i],nd[k]); 80 } 81 } 82 sort(e,e+cnt,cmp); 83 memset(fa,-1,sizeof(fa)); 84 double ans=Kruskal(); 85 if(kas!=1) 86 { 87 printf("\n"); 88 } 89 printf("Scenario #%d\nFrog Distance = %.3f\n",kas++,ans); 90 } 91 return 0; 92 }
Kruskal
相关文章推荐
- 【算法系列学习】SPFA邻接表最短路 [kuangbin带你飞]专题四 最短路练习 F - Wormholes
- 【算法系列学习】Dijkstra求最短路 [kuangbin带你飞]专题四 最短路练习 D - Silver Cow Party
- 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 F - Piggy-Bank 【完全背包问题】
- 【算法系列学习】线段树 单点覆盖,区间查询最大值 [kuangbin带你飞]专题七 线段树 B - I Hate It
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 G - 免费馅饼
- 【算法系列学习】状压dp [kuangbin带你飞]专题十二 基础DP1 D - Doing Homework
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 B - Ignatius and the Princess IV
- 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开
- 【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵
- 【算法系列学习】线段树 区间修改,区间求和 [kuangbin带你飞]专题七 线段树 C - A Simple Problem with Integers
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 E - Super Jumping! Jumping! Jumping!
- 【算法系列学习】[kuangbin带你飞]专题二 搜索进阶 D - Escape (BFS)
- 【算法系列学习】DP和滚动数组 [kuangbin带你飞]专题十二 基础DP1 A - Max Sum Plus Plus
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 C - Monkey and Banana
- [kuangbin带你飞]专题四 最短路练习 M POJ 1062
- [kuangbin带你飞]专题四 最短路练习 -F
- [kuangbin带你飞]专题四 最短路练习 R HDU 437
- [kuangbin带你飞]专题四 最短路练习H,I,J
- [kuangbin带你飞]专题四 最短路练习D