1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #define maxn 100010 #define maxm 100010 #define maxk 50 #define INF 1000000000000000000 #define ll long long using namespace std;
int n, m, q;
int fa[maxn]; void init_fa(int n) { for (int i = 1; i <= n; ++i) fa[i] = i; }
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
inline void merge(int x, int y) { int fx = find(x), fy = find(y); if (fx == fy) return ; fa[fy] = fx; }
struct Edge { int fr, to, next, w; } e[maxm * 2], E[maxm]; int c1, head[maxn]; inline void add_edge(int u, int v, int w) { e[c1].to = v; e[c1].w = w; e[c1].next = head[u]; head[u] = c1++; }
int f[maxn][21], dep[maxn]; ll dis[maxn]; void dfs(int u, int fa) { for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to, w = e[i].w; if (v == fa) continue; f[v][0] = u; dep[v] = dep[u] + 1; dis[v] = dis[u] + w; dfs(v, u); } }
void init_lca() { for (int j = 1; j <= 20; ++j) for (int i = 1; i <= n; ++i) f[i][j] = f[f[i][j - 1]][j - 1]; }
int get_lca(int x, int y) { if (dep[x] < dep[y]) swap(x, y); for (int i = 20; ~i; --i) if (dep[f[x][i]] >= dep[y]) x = f[x][i]; if (x == y) return x; for (int i = 20; ~i; --i) if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; return f[x][0]; }
struct Queue { int k; ll d;
friend bool operator < (const Queue &u, const Queue &v) { return u.d > v.d; } }; bool vis[maxn]; ll d[maxk][maxn]; void dijkstra(ll *dis, int s) { for (int i = 1; i <= n; ++i) dis[i] = INF, vis[i] = 0; priority_queue<Queue> Q; dis[s] = 0; Q.push({ s, dis[s] }); while (!Q.empty()) { int u = Q.top().k; Q.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] > dis[u] + w) { dis[v] = dis[u] + w; Q.push({ v, dis[v] }); } } } }
int main() { fill(head, head + maxn, -1); ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m; init_fa(n); set<int> S; int cnt = 0; for (int i = 1; i <= m; ++i) cin >> E[i].fr >> E[i].to >> E[i].w; for (int i = 1; i <= m; ++i) { int u = E[i].fr, v = E[i].to, w = E[i].w; if (find(u) == find(v)) { S.insert(u); S.insert(v); continue; } merge(u, v); add_edge(u, v, w); add_edge(v, u, w); } dep[1] = 1; dfs(1, 0); init_lca(); fill(head, head + maxn, -1); c1 = 0; for (int i = 1; i <= m; ++i) add_edge(E[i].fr, E[i].to, E[i].w), add_edge(E[i].to, E[i].fr, E[i].w); for (auto u : S) dijkstra(d[++cnt], u); cin >> q; while (q--) { int x, y; cin >> x >> y; ll ans = dis[x] + dis[y] - 2 * dis[get_lca(x, y)]; for (int i = 1; i <= cnt; ++i) ans = min(ans, d[i][x] + d[i][y]); cout << ans << "\n"; } return 0; }
|