题意:题意好理解,一个人步行的速度为每小时10公里,坐地铁的速度为40公里每小时。首先给出你两个点,分别是起点和终点。然后给出若干条铁路,每个铁路上至少有两个站点(也就是这条起点和终点),然后-1,-1为结束。问你从起点到终点最短需要多长时间。
题解:如何建图是一个问题。数据较小用临界矩阵来存图,我们可以把所有的站点,和起点终点当作图中的点来存图。存起来比较麻烦,需要存每个站点的时间,还有人到每个站点的时间。明白了要存什么,就看具体代码实现。spfa求最短路。
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 30005;
const double INF = 1e9+0.0;
struct node{
int x;
int y;
}p[N];
int cnt,sum;
double dis[N];
int vis[N];
double ma[250][250];
double walk(node a,node b){
return sqrt((double)(a.x-b.x) * (double)(a.x - b.x) + (double)(a.y - b.y) * (double)(a.y - b.y)) * 60.0 /10000.0;
}
double subway(node a,node b){
return sqrt((double)(a.x-b.x) * (double)(a.x - b.x) + (double)(a.y - b.y) * (double)(a.y - b.y)) * 60.0 /40000.0;
}
void spfa(){
memset(vis,0,sizeof(vis));
for(int i = 0 ; i < 240 ; i ++)
dis[i] = INF ;
queue <int> q;
dis[1] = 0;
vis[1] = 1;
q.push(1);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = 0;
for(int i = 1; i < cnt ; i++){
if(dis[i] > dis[u] + ma[u][i]){
dis[i] = dis[u] + ma[u][i];
if(!vis[i]){
vis[i] = 1;
q.push(i);
}
}
}
}
}
int main(){
cnt = 3;
sum = 0;
for(int i = 0 ; i < 240 ; i ++) // 初始化
for(int j = 0 ;j < 240 ; j++)
ma[i][j] = i == j ? 0.0 : INF;
scanf("%d%d%d%d",&p[1].x,&p[1].y,&p[2].x,&p[2].y); //输入起点和终点
ma[2][1] = ma[1][2] = walk(p[1],p[2]); // 把起点当作第一个点 ,把终点当作第二个点
while(~scanf("%d%d",&p[cnt].x,&p[cnt].y)){ // 输入若干铁路。
if(p[cnt].x == -1 && p[cnt].y == -1){ // 结束标识
sum = 0 ; // 当sum=0 表示现在输入一条全新的铁路。
continue;
}
for(int i = 1; i < cnt - sum ; i ++) // 计算人到每个站点的时间
ma[i][cnt] = ma[cnt][i] = walk(p[cnt],p[i]);
if(sum) // 若sum = 1 则,计算这条铁路到上个站点的时间。 若sum=0就不计算。很精髓
ma[cnt][cnt-1] = ma[cnt - 1][cnt] = subway(p[cnt],p[cnt-1]);
cnt ++;
sum = 1;
}
// for(int i = 1 ; i < cnt ; i++){
// for(int j = 1; j < cnt ;j ++)
// cout << ma[i][j] << " ";
// cout << endl;
// }
spfa();
printf("%d\n",(int)(dis[2] + 0.5));
return 0;
}