Question Link
题目分析
第一、用时间作为边的代价。
那么,你可以从一个点走到任意一个点,此时行走的时间就是代价。
但是,你还可以,从在相邻,地铁,的结点中,乘坐地铁,那么,乘坐地铁的时间,就是代价。
为什么只能是从相邻的地铁站中呢? 因为 1 到 3 结点必须经过 2, 换句话说 1 到 3 一般是折线,不是直线。
下面是其他人的题解代码,我觉得很清晰。到自己能写出这样的代码是,再将博客,公开发表。
/*
dijkstra
Memory 500K
Time 0MS
*/
#include <stdio.h>
#include <math.h>
#define MAXV 203
#define inf 1e8
#define min(a,b) (a<b?a:b)
#define distance(t,s) sqrt((double) ( (t.x-s.x)*(t.x-s.x)+(t.y-s.y)*(t.y-s.y)) )
typedef struct{
int x,y;
}Point;
Point point[MAXV],a;
int n;
double map[MAXV][MAXV];
void dijkstra(){
int i,j,v,vis[MAXV];
double min,d[MAXV];
for(i=1;i<n;i++){
vis[i]=0;
d[i]=map[1][i];
}
for(i=1;i<n;i++){
min=inf;
for(j=1;j<n;j++)
if(!vis[j] && d[j]<min){
min=d[j];
v=j;
}
vis[v]=1;
for(j=1;j<n;j++)
if(!vis[j] && d[j]>map[v][j]+d[v])
d[j]=map[v][j]+d[v];
}
printf("%d\n",(int)(d[2]+0.5));
}
int ex(Point t){
int i;
for(i=1;i<n;i++){
if(t.x==point[i].x && t.y==point[i].y) break;
}
if(i==n) point[n++]=t;
return i;
}
int main(){
int subway[MAXV],scnt;
int i,j,t;
for(i=1;i<MAXV;i++)
for(j=1;j<MAXV;j++)
if(i==j) map[i][j]=0;
else map[i][j]=inf;
n=1;
scanf("%d%d%d%d",&point[n].x,&point[n].y,&point[n+1].x,&point[n+1].y);
n+=2;
while(~scanf("%d%d",&a.x,&a.y)){
t=n;
scnt=0;
subway[scnt++]=ex(a); //要判断输入的点是否已经存在
while(scanf("%d%d",&a.x,&a.y) && (a.x!=-1 && a.y!=-1)){
subway[scnt++]=ex(a);
}
for(i=1;i<scnt;i++) //地铁的站的时间只能是相邻的站点能到,不能从站点1直接到站点n
map[subway[i]][subway[i-1]]=map[subway[i-1]][subway[i]]=distance(point[subway[i]],point[subway[i-1]])*3.0/2000.0;
}
for(i=1;i<n;i++)
for(j=1;j<=i;j++)
map[i][j] = map[j][i] = min(map[i][j],distance(point[i],point[j])*3.0/500.0);
dijkstra();
return 0;
}