poj_2253_prim / floyed

来源:互联网 发布:java通过ip获取地区 编辑:程序博客网 时间:2024/06/11 02:33

题目描述:

本题要求得青蛙跳到另一个青蛙石头上所走的路径中,求得在最长步长(每条路径里都有一个最长步长)最短的,那个步长值。出发点1,结束点2。

思路:

法一、利用最小生成树法(Prim),每次选进一个点(从集合S到集合U,选择边最短的链接点),记录的选进的边权最大的那个值,选到2点后推出。//注:这里权值最大的边,必然为通往目标节点2这条路径上的边。

这个思路同迪杰斯特拉,只是这两个算法用的优先序列D[]的意义不同。prim中优先序列存边长,Dijstra中优先序列存从原点到j的路径长。时间复杂度为O(v(logv+E))。

法二、floyed变形。floyed为求每对点的最短距离。改原始存的D[v][w]意义为v->w的所有路径中最长步长的最短步长。三个循环遍历了所有v->w的可能路径。那么在每个循环中,更新D[v][w]= min(D[v][w], max(D[v][u],D[u][w]))。

附:这里代码里的图直接存成邻接矩阵,本题为无向图,也可选择压缩。

 

//法一:

#include <stdio.h>
#include <stdlib.h>
#define N 201
#define Infinity 10000

typedef struct{
   double x;
   double y;
}STONE;

STONE stone[N];
double G[N][N]; //图信息
int final[N];
double D[N];

main()
{
   int k=1,n,i,j,tmp;
   double max,min;
  scanf("%d",&n);
   while(n!=0)
   {
      for(i=1;i<=n;i++)
         scanf("%lf %lf",&stone[i].x,&stone[i].y);
            
      for(i=1;i<=n;i++)
      {
         for(j=1;j<=n;j++)
             G[i][j] = sqrt((stone[i].x - stone[j].x)*(stone[i].x - stone[j].x)+ (stone[i].y - stone[j].y)*(stone[i].y - stone[j].y));
         final[i] = 0;
      }
      //prim
      //initialize:final , D[]存储未选辑各个点到已选集的最短边
      final[1] = 1;
      for(i=2; i<=n; i++)
         D[i] = G[1][i];
      
      max = -1;
      for(i=2;i<=n;i++)//遍历点
      {
         min = Infinity;
         for(j=2;j<=n;j++)
         {
            if(!final[j] &&min>D[j])
            {
               min = D[j];
               tmp = j;
            }
         }
         if(min == Infinity) //图不连通
            break;
         final[tmp] = 1;
         if(max < min)
            max = min;
         if(tmp == 2)
            break;
            
         for(j=1;j<=n;j++)//更新权值
            if(D[j] > G[tmp][j])
               D[j] = G[tmp][j];
      }
      printf("Scenario #%d\n",k++);
      printf("Frog Distance = %.3f\n\n",max);
      scanf("%d",&n);
   }//end while
  
   //system("pause");
   return 0;

}

法二:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 201
#define Infinity 10000

typedef struct {
   double x;
   double y;
}STONE;

STONE stone[N];
double G[N][N];
double D[N][N];

main()
{
   int n, u, v, w, i,j,k=1;
   double max;
  scanf("%d",&n);
   while(n!=0)
   {
      for(i=1;i<=n;i++)
         scanf("%lf %lf",&stone[i].x,&stone[i].y);
            
      for(i=1;i<=n;i++)
         for(j=1;j<=n;j++)
         {
             G[i][j] = sqrt((stone[i].x - stone[j].x)*(stone[i].x - stone[j].x)+ (stone[i].y - stone[j].y)*(stone[i].y - stone[j].y));
             D[i][j] = G[i][j];
         }
      
      //floyed
      for(u=1; u<=n; u++)
         for(v=1; v<=n; v++)
            for(w=1; w<=n; w++)
            {
               if(v!=w)
               {
                  max = D[v][u] > D[u][w] ? D[v][u] : D[u][w];
                  D[v][w] = D[v][w] < max ? D[v][w] : max;
               }
            }
      printf("Scenario #%d\n",k++);
      printf("Frog Distance = %.3f\n\n",D[1][2]);
      scanf("%d",&n);
   }
   //system("pause");
   return 0;
}

原创粉丝点击