题目大意:首先给你两个坐标,一个是你家里的坐标,一个是你学校的坐标,然后接下来有若干条地铁线,每条地铁线上有若干个站点,给出每个站点的坐标,有这些点,这些点当中有距离,这个距离的单位是米,现在告诉你走路是10km/h,做地铁的话是40km/h,问你从家里到学校所花费的最短时间(分钟)
思路:建图比较麻烦,注意地铁站直接只能到达相邻的,并且算过权值之后还需要用步行的时间把所有节点间权值更新一遍。之后就是spfa
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#define inf 1e8
using namespace std;
const int maxn = 300 + 10;
double g[maxn][maxn], d[maxn];
struct Point{
int x, y;
};
Point u, v, p[maxn];
int n, tot, sta[maxn], vis[maxn];
double dist(Point a, Point b){
return sqrt( (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) );
}
int ex(Point u){
int i;
for(i = 1; i < n; i++)
if(p[i].x == u.x && p[i].y == u.y) break;
if(i == n) p[n++] = u;
return i;
}
void spfa(){
queue<int> q;
for(int i = 2; i <= n; i++)
d[i] = inf;
q.push(1);
vis[1] = 1;
int u;
while(!q.empty()){
u = q.front(); q.pop(); vis[u] = 0;
for(int i = 1; i <= n; i++){
if(d[i] > d[u] + g[u][i]){
d[i] = d[u] + g[u][i];
if(!vis[i]) {q.push(i); vis[i] = 1;}
}
}
}
printf("%d\n", (int)(d[2]+0.5));
}
int main(){
freopen("poj2502.in", "r", stdin);
Point u, v;
for(int i = 1; i < maxn; i++)
for(int j = 1; j < maxn; j++)
if(i == j) g[i][j] = 0;
else g[i][j] = inf;
scanf("%d%d%d%d", &u.x, &u.y, &v.x, &v.y);
n = 1; p[n++] = u; p[n++] = v;
while(~scanf("%d%d", &u.x, &u.y)){
tot = 0;
sta[++tot] = ex(u);
while(scanf("%d%d", &u.x, &u.y) && !(u.x == -1 && u.y == -1)){
sta[++tot] = ex(u);
}
for(int i = 1; i < tot; i++){
g[sta[i]][sta[i+1]] = g[sta[i+1]][sta[i]] = dist( p[sta[i]], p[sta[i+1]] )*3.0/2000.0;
}
}
n--;
for(int i = 1; i < n; i++){
for(int j = i+1; j <= n; j++){
g[i][j] = g[j][i] = min(g[i][j], dist(p[i], p[j])*3.0/500.0);
}
}
spfa();
return 0;
}