1. 程式人生 > >Subway(最短路)

Subway(最短路)

題目連結:[POJ 2502]Subway[最短路]
題意分析:
你從A到B上學,可以選擇走路或者到地鐵站搭乘地鐵到達,走路速度10km/h,地鐵速度40km/h,你可以任意站點下車上車,問:最快要多少分鐘到達學校?
解題思路:
建圖求最短路即可。
這裡寫圖片描述
地鐵每條線路相鄰站點之間建一條雙向邊,速度40km/h
所有點之間建雙向邊,速度10km/h
over。
個人感受:
心塞!!!spfa寫錯了超級粗心的錯誤,debug有兩個多小時。然後debug完發現還是WA了,最終才知道是建圖出了問題!!!當初覺得同一條線路肯定能搭地鐵最快,沒想到還能走路!!!TAT。給個這種樣例,紅色是地鐵,藍色是走路。如下:
這裡寫圖片描述
具體程式碼如下:

#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN = 311;
const int INF = 0x7f7f7f7f;

struct Edge{
    int to, next;
    double w;
}edge[2 * MAXN * MAXN];
int head[MAXN], cnt, sta[MAXN];
double x[MAXN], y[MAXN], dis[MAXN];
bool in[MAXN];

void
add_edge(int from, int to, double w) { edge[cnt].to = to; edge[cnt].w = w; edge[cnt].next = head[from]; head[from] = cnt++; } void double_make(int from, int to, double w) { add_edge(from, to, w); add_edge(to, from, w); } double getdis(int a, int b) { double delx = x[a] - x[b], dely = y[a] - y[b]; return
sqrt(delx * delx + dely * dely); } void spfa(int s) { dis[s] = 0; int top = 0; sta[top++] = s; in[s] = 1; while (top) { int cur = sta[--top]; in[cur] = 0; // in[cur] 寫成了 in[s]。哭瞎。 for (int i = head[cur]; ~i; i = edge[i].next) { Edge &e = edge[i]; if (dis[e.to] > dis[cur] + e.w) { dis[e.to] = dis[cur] + e.w; if (!in[e.to]) { in[e.to] = 1; sta[top++] = e.to; } } } } } int main() { memset(head, -1, sizeof head); for (int i = 0; i < 311; ++i) dis[i] = INF; scanf("%lf %lf %lf %lf", &x[0], &y[0], &x[1], &y[1]); int n = 2, last = 0; while (~scanf("%lf %lf", &x[n], &y[n])) { if (x[n] == -1 && y[n] == -1) { last = 0; continue; } if (last) double_make(last, n, getdis(last, n) * 3.0 / 2000.0); last = n++; } for (int i = 0; i < n; ++i) for (int j = i + 1; j < n; ++j) { double_make(i, j, getdis(i, j) * 3.0 / 500.0); // 不管怎麼樣,在每個站點都有權利選擇走到其它站點 } spfa(0); printf("%.0f\n", round(dis[1])); return 0; }