以 1,2,n 为起点跑3次 bfs 或者 spfa
那么 ans = min(ans, dis[1][i] * B + dis[2][i] * E + dis[3][i] * P) (1 <= i <= n)
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #define N 40001 #define LL long long #define min(x, y) ((x) < (y) ? (x) : (y)) int B, E, P, n, m, cnt; int dis[4][N], head[N], to[N << 1], next[N << 1]; bool vis[N]; std::queue <int> q; LL ans = ~(1 << 31); inline int read() { int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f; } inline void add(int x, int y) { to[cnt] = y; next[cnt] = head[x]; head[x] = cnt++; } inline void spfa(int s, int k) { int i, v, u; memset(vis, 0, sizeof(vis)); memset(dis[k], 127, sizeof(dis[k])); q.push(s); dis[k][s] = 0; while(!q.empty()) { u = q.front(); q.pop(); vis[u] = 0; for(i = head[u]; i ^ -1; i = next[i]) { v = to[i]; if(dis[k][v] > dis[k][u] + 1) { dis[k][v] = dis[k][u] + 1; if(!vis[v]) { q.push(v); vis[v] = 1; } } } } } int main() { int i, x, y; B = read(); E = read(); P = read(); n = read(); m = read(); memset(head, -1, sizeof(head)); for(i = 1; i <= m; i++) { x = read(); y = read(); add(x, y); add(y, x); } spfa(1, 1); spfa(2, 2); spfa(n, 3); for(i = 1; i <= n; i++) ans = min(ans, (LL)(dis[1][i] * B + dis[2][i] * E + dis[3][i] * P)); printf("%lld ", ans); return 0; }