Subway POJ - 2502
小k要从家去学校,他可以选择步行或者地铁,步行的速度是10km/h,地铁的速度是40km/h。假设小k非常的幸运,每次他到地铁站就立刻会有地铁。小k可以随意上下地铁,并且可以在地铁线路之间转换。所有的地铁运行都是双向的。
Input
输入第一行包括家和学校的x,y坐标,接下来是若干条地铁线。
每条地铁线包括站点的x,y坐标,有序排列,假设地铁在相邻的两站之间直线运行,每条地铁线至少有两个站,地铁线的描述以-1,-1结束。
该市最多有200个地铁站。
Output
输出是上学所需的时间,四舍五入到最近的分钟,采取最快的路线。
Examples
Sample Input
0 0 10000 1000
0 200 5000 200 7000 200 -1 -1
2000 600 5000 600 10000 600 -1 -1
Sample Output
21
Hint
题意:
输出四舍五入
题解:
这道题目的最短路求法其实很简单, 直接上模板就可以, 但难点主要在建图上.
显然我们需要除了要构建地铁站直接的边, 还需要构建起点和终点到所有地铁站的边.
经验小结:
很多题目的图需要自己去构建
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const int inf = 1<<30;
const LL maxn = 410;
int sx, sy, ex, ey;
struct node{
int x, y;
node(int xx, int yy){x = xx, y = yy;}
node(){}
}es[maxn];
int len = 0;
double w[maxn][maxn];
double getDis(double x1, double y1, double x2, double y2){
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double d[maxn];
typedef pair<double, int> P;
bool used[maxn];
void Dijkstra(int s){
priority_queue<P, vector<P>, greater<P> > q;
fill(d, d+maxn, inf);
d[s] = 0;
q.push(P(d[s], s));
while(!q.empty()){
P cur = q.top();
q.pop();
int u = cur.second;
if(used[u]) continue;
used[u] = true;
for(int v = 1; v <= len; ++v){
if(d[u]+w[u][v] < d[v]){
d[v] = d[u]+w[u][v];
q.push(P(d[v], v));
}
}
}
}
int main()
{
double x, y;
cin >> x >> y;
es[++len] = node(x, y);
cin >> x >> y;
es[++len] = node(x, y);
//1为起点, 2为终点
int last= 2;
while(cin >> x >> y){
//地铁建图
if(x==-1.0 && y==-1.0){
for(int i = last+1; i < len; ++i){
double dis = getDis(es[i].x, es[i].y, es[i+1].x, es[i+1].y);
w[i][i+1] = w[i+1][i] = dis/40000.0;
}
last = len;
continue;
}
es[++len] = node(x, y);
}
//步行补边
for(int i = 1; i <= len; ++i)
for(int j = i+1; j <= len; ++j)
if(w[i][j] == 0)
w[i][j] = w[j][i] = getDis(es[i].x, es[i].y, es[j].x, es[j].y)/10000.0;
Dijkstra(1);
cout << (int)(d[2]*60.0+0.5) << endl;
return 0;
}