pku 2253小结

刚刚开始搞图论,才做了两道最短路径题,一道是: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;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(pku 2253小结)