SPFA,2RE,无向图的边数为题目描述的两倍。
# include <cstdio> # include <cstring> # include <queue> using namespace std; # define N 20000 + 5 # define M (50000 + 5) * 2 # define INF 550000000 int n, m, src, des; int first[N], d[N]; bool inq[N]; int u[M], v[M], w[M], next[M]; void read_graph(void) { scanf("%d%d%d%d", &n, &m, &src, &des); memset(first, -1, sizeof(first[0])*n); for (int e = 0; e < 2*m; e += 2) { scanf("%d%d%d", &u[e], &v[e], &w[e]); next[e] = first[u[e]], first[u[e]] = e; u[e+1] = v[e], v[e+1] = u[e], w[e+1] = w[e]; next[e+1] = first[u[e+1]], first[u[e+1]] = e+1; } } void spfa(int src, int n) { queue <int> Q; memset(inq, false, sizeof(inq[0])*n); for (int i = 0; i < n; ++i) d[i] = (i==src ? 0:INF); Q.push(src); while (!Q.empty()) { int x = Q.front(); Q.pop(); inq[x] = false; for (int e = first[x]; e != -1; e = next[e]) if (d[x] < INF && d[x]+w[e] < d[v[e]]) { d[v[e]] = d[x] + w[e]; if (inq[v[e]] == false) { inq[v[e]] = true; Q.push(v[e]); } } } } int main() { int T; scanf("%d", &T); for (int i = 1; i <= T; ++i) { printf("Case #%d:", i); read_graph(); spfa(src, n); if (d[des] >= INF) puts(" unreachable"); else printf(" %d\n", d[des]); } return 0; }