Dijkstra算法的简单变形 pku 2253 Frogger

题目链接:

http://acm.pku.edu.cn/JudgeOnline/problem?id=2253

 

 

 

#include <stdio.h>
#include <cmath>
#include <memory.h>

#define MAX_STONE 205

#define INFINITE 1<<20

#define Max(x,y) ((x) > (y) ? (x) : (y))
#define Min(x,y) ((x) < (y) ? (x) : (y))

struct Stone{
 int x;
 int y;
}stones[MAX_STONE];

int map[MAX_STONE][MAX_STONE];
int distance[MAX_STONE];
int jumped[MAX_STONE];

int n;
//贪心 + DP
//distance[k]为从源点跳到k节点时所跳的最长距离
//diantance[1] = 0;
//diantance[k] = Min(diantance[k],Max(distance[curr_Location],map[curr_Location][k]));
//distance[curr_Location]从源点跳到curr_Location时跳过的最长距离
//map[curr_Location][k]以curr_Location为中间节点跳到k的距离
//选出其中的最大值----如果是从curr_Location跳到k的话
//diantance[k]因为经过初始化,为源点到k的距离
//要么是直接从源点跳到k,要么经过中间节点curr_Location到k.
//取其中的最小值就可以.
void Dijkstra(){
 int i,j;
 //初始化距离
 for(i = 1;i <= n;i++)
  distance[i] = map[i][1];
 //源点加入S集合中
 jumped[1] = 1;
 for(i =0;i < n - 1;i++){
  //选出下一个节点
  int min = INFINITE;
  int curr;
  for(j = 1;j <= n;j++)
   if(jumped[j] == 0 && distance[j] < min){
    min = distance[j];
    curr = j;
   }
  jumped[curr] = 1;
  //更新diantance[]数组
  for(j = 1;j <= n;j++)
   if(jumped[j] == 0 && map[curr][j] != INFINITE){
    distance[j] = Min(distance[j],Max(distance[curr],map[curr][j]));
   }
 }
}
int main(){
 int Scenario = 0;
 int i,j;
 //FILE *fp = fopen("Frogger.txt","r");
 while(scanf("%d",&n)/*fscanf(fp,"%d",&n)*/,n){
  for(i = 1;i <= n;i++)
   scanf("%d%d",&(stones[i].x),&(stones[i].y));
   //fscanf(fp,"%d%d",&(stones[i].x),&(stones[i].y));
  memset(map,INFINITE,sizeof(map));
  memset(jumped,0,sizeof(jumped));
  for(i = 1;i <= n;i++)
   for(j = i;j <=n;j++)
    map[i][j] = map[j][i] = (stones[i].x - stones[j].x) * (stones[i].x - stones[j].x) +
          (stones[i].y - stones[j].y) * (stones[i].y - stones[j].y);
  Dijkstra();
  printf("Scenario #%d/nFrog Distance = %.3f/n/n",++Scenario,(sqrt((double)distance[2])));
 }
 return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值