Dijkstra+计算几何 POJ 2502 Subway
题意:列车上行驶40, 其余走路速度10.问从家到学校的最短时间
分析:关键是建图:相邻站点的速度是40,否则都可以走路10的速度.读入数据也很变态.
#include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <queue> using namespace std; const int N = 2e2 + 5; const int E = N * N; const double INF = 1e30; struct Point { double x, y; }p[N]; bool vis[N]; double d[N]; double w[N][N]; double sx, sy, ex, ey; int tot; void Dijkstra(int s) { memset (vis, false, sizeof (vis)); for (int i=1; i<=tot; ++i) { d[i] = INF; } d[s] = 0; for (int i=1; i<=tot; ++i) { double mn = INF; int x = -1; for (int j=1; j<=tot; ++j) { if (!vis[j] && mn > d[j]) mn = d[x=j]; } if (x == -1) break; vis[x] = true; for (int j=1; j<=tot; ++j) { if (!vis[j] && d[j] > d[x] + w[x][j]) { d[j] = d[x] + w[x][j]; } } } } double squ(double x) { return x * x; } double get_cost(Point p1, Point p2, int v) { double dis = sqrt (squ (p1.x - p2.x) + squ (p1.y - p2.y)) / 1000; return dis / v; } int main(void) { while (scanf ("%lf%lf%lf%lf", &sx, &sy, &ex, &ey) == 4) { for (int i=1; i<N; ++i) { for (int j=1; j<N; ++j) { w[i][j] = INF; } } tot = 1; double x, y, l = tot + 1; p[tot].x = sx; p[tot].y = sy; while (scanf ("%lf%lf", &x, &y) == 2) { if (x == -1 && y == -1) { for (int i=l; i<tot; ++i) { double tim = get_cost (p[i], p[i+1], 40); if (w[i][i+1] > tim) { w[i][i+1] = w[i+1][i] = tim; } } l = tot + 1; continue; } p[++tot].x = x; p[tot].y = y; } p[++tot].x = ex; p[tot].y = ey; for (int i=1; i<tot; ++i) { for (int j=i+1; j<=tot; ++j) { double tim = get_cost (p[i], p[j], 10); if (w[i][j] > tim) { w[i][j] = w[j][i] = tim; } } } Dijkstra (1); printf ("%.0f\n", d[tot] * 60); } return 0; }
编译人生,运行世界!