有向圖,P 個站點 (1 為中心站 CCS),Q 條單向邊。每天志願者從 1 出發去各站點,晚上再從各站點回 1。求每天總車費最小值(即 1 到所有點最短路之和 + 所有點到 1 最短路之和)。P, Q ≤ 1,000,000。
to, w, next,head[u] 指向第一條邊索引。pair 進堆,或自定義結構體。#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 1000005;
const int INF = 0x3f3f3f3f;
struct Edge { int to, w, next; } e[MAXN];
int head[MAXN], ecnt;
void add_edge(int u, int v, int w) {
e[ecnt] = {v, w, head[u]};
head[u] = ecnt++;
}
ll dijkstra(int n, int s) {
vector dis(n+1, INF);
vector vis(n+1, 0);
priority_queue, vector>, greater>> pq;
dis[s] = 0; pq.emplace(0, s);
while (!pq.empty()) {
auto [d, u] = pq.top(); pq.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i=head[u]; ~i; i=e[i].next) {
int v = e[i].to, w = e[i].w;
if (dis[v] > d + w) {
dis[v] = d + w;
pq.emplace(dis[v], v);
}
}
}
ll sum = 0;
for (int i=1;i<=n;i++) sum += dis[i];
return sum;
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
int T; cin >> T;
while (T--) {
int P, Q; cin >> P >> Q;
fill(head+1, head+P+1, -1); ecnt = 0;
vector> edges;
edges.reserve(Q);
for (int i=0;i>u>>v>>w;
edges.emplace_back(u,v,w);
add_edge(u,v,w);
}
ll ans1 = dijkstra(P, 1);
// 反向圖
fill(head+1, head+P+1, -1); ecnt = 0;
for (auto [u,v,w] : edges) add_edge(v,u,w);
ll ans2 = dijkstra(P, 1);
cout << ans1 + ans2 << '\n';
}
return 0;
}