刚刚开始搞图论,才做了两道最短路径题,一道是:pku 1062(昂贵的聘礼),另一道是pku 2253(Frogger),都可以用Dijkstra算法解决,Dijkstra真是太经典了,还有经常听人说spfa算法,至今还不知道是什么算法,只知道是一种求最短路径的高效算法,貌似还可以处理负数,真应该好好去研究一下。。。
本题原文链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=2253
本题的关键就是要搞清楚两点:1,要保证从Freddy 到Fiona的距离尽可能的短。
2,要保证在尽可能短的路经中Freddy从一块石头跳到另一块石头的距离最大。
这两点似乎看起来挺矛盾的,其实不然。
那么既然要求最短路径的话,我们不难想到Dijkstra这样高效的算法。
代码实现:
#include<iostream>
#include<cmath>
#include<stdio.h>
#include<string.h>
using namespace std;
const int MAX=203;
struct point
{
int x,y;
}sq[MAX];
double map[MAX][MAX];
double dist[MAX]; //记录从点1到点i路径上的两点任意的之间最大距离
int visit[MAX]; //记录该节点是否已经访问
int n;
void dijkstra()
{
int k;
for(int i=1;i<=n;i++)
dist[i]=map[1][i];
for(int j=1;j<=n;j++)
{
k=0;
for(int i=1;i<=n;i++)//z这个for就是找最短距离,来保证所要求的整条路径的长度尽可能小
if(!visit[i])
if(k==0||dist[i]<dist[k])
k=i;
visit[k]=1;
for(int i=1;i<=n;i++)
if(map[k][i]>0)
dist[i]=min(max(dist[k],map[k][i]),dist[i]); // 求路径上两点之间的最大距离
}
}
int main()
{
int T=0;
while(scanf("%d",&n)&&n)
{
memset(map,0,sizeof(map));
memset(visit,0,sizeof(visit));
memset(dist,0,sizeof(dist));
for(int i=1;i<=n;i++)
scanf("%d%d",&sq[i].x,&sq[i].y);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
map[i][j]=map[j][i]=(double)sqrt((sq[i].x-sq[j].x)*(sq[i].x-sq[j].x)+(sq[i].y-sq[j].y)*(sq[i].y-sq[j].y));
dijkstra();
printf("Scenario #%d/n",++T);
printf("Frog Distance = %.3f/n",dist[2]);
printf("/n");
}
return 0;
}