牛客国庆集训派对Day3 I Metropolis
思路:
多源点最短路
只要两个不同源点的最短路相遇,我们就更新两个源点的答案
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pli, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e5 + 100; const LL INF = 0x7f7f7f7f7f7f7f7f; vector<pii> g[N]; priority_queue<piii, vector<piii>, greater<piii> > q; pli d[N]; LL dis[N]; vector<int> st; void dijkstra() { while(!q.empty()) { piii now = q.top(); q.pop(); int u = now.fi.se; if(d[u].fi < now.fi.fi) continue; for (pii t : g[u]) { int v = t.fi; int w = t.se; if(d[v].fi > w + now.fi.fi) { d[v].se = now.se; d[v].fi = w + now.fi.fi; q.push(piii{{d[v].fi, v}, now.se}); } if(d[v].se && d[v].se != now.se) { int u1 = d[v].se; int u2 = now.se; dis[u1] = min(dis[u1], d[v].fi+now.fi.fi + w); dis[u2] = min(dis[u2], d[v].fi+now.fi.fi + w); } } } } int main() { int n, m, p, u, v, w; scanf("%d %d %d", &n, &m, &p); for (int i = 1; i <= n; i++) d[i].fi = INF, d[i].se = 0, dis[i] = INF; for (int i = 0; i < p; i++) scanf("%d", &u), d[u] = pii{0, u}, q.push(piii{{0, u}, u}), st.pb(u); for (int i = 0; i < m; i++) { scanf("%d %d %d", &u, &v, &w); g[u].pb(pii{v, w}); g[v].pb(pii{u, w}); } dijkstra(); for (int x : st) printf("%lld ", dis[x]); return 0; }