https://vjudge.net/contest/66569#problem/B
类试题:noip2013 货物运输
方法一: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 const double inf=0x3f3f3f3f; 8 using namespace std; 9 int n; 10 struct node 11 { 12 int x,y; 13 }nd[203]; 14 double map[203][203]; 15 double dist(node a,node b) 16 { 17 return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y)); 18 } 19 double dis[203]; 20 void Dijkstra() 21 { 22 bool vis[203]; 23 memset(vis,0,sizeof(vis)); 24 dis[1]=0.0; 25 for(int i=2;i<=n;i++) 26 { 27 dis[i]=inf; 28 } 29 int v; 30 for(int i=1;i<=n;i++) 31 { 32 int m=inf; 33 for(int k=1;k<=n;k++) 34 { 35 if(!vis[k]&&dis[k]<m) 36 { 37 m=dis[k]; 38 v=k; 39 } 40 } 41 vis[v]=1; 42 //对以v为顶点的边进行松弛 43 for(int k=1;k<=n;k++) 44 { 45 if(!vis[k]) 46 { 47 dis[k]=min(dis[k],max(dis[v],map[v][k])); 48 } 49 } 50 } 51 } 52 int main() 53 { 54 int kas=1; 55 while(scanf("%d",&n)&&n) 56 { 57 for(int i=1;i<=n;i++) 58 { 59 scanf("%d%d",&nd[i].x,&nd[i].y); 60 for(int k=1;k<i;k++) 61 { 62 map[i][k]=map[k][i]=dist(nd[i],nd[k]); 63 } 64 } 65 Dijkstra(); 66 if(kas!=1) 67 { 68 printf("\n"); 69 } 70 printf("Scenario #%d\n",kas++); 71 printf("Frog Distance = %.3f\n",dis[2]); 72 } 73 return 0; 74 }