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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| #include<bits/stdc++.h> using namespace std; #define ll long long typedef pair<int, int> pii; const int INF = 0x3f3f3f3f; const int maxn = 1e5 + 10; int n, m, Q; int nn; struct edge { int v, w; }; vector<edge>gg[maxn], G[maxn]; void add_edge(int u, int v, int w) { G[u].push_back((edge) { v, w }); G[v].push_back((edge) { u, w }); } int dis[maxn]; int dfn[maxn], low[maxn], fa[maxn], dep[maxn]; int cnt; int len[maxn], zn[maxn]; int S[maxn]; void solve_cir(int rt, int v, int w) { int top = dep[v] - dep[rt] + 1, sum = w, Dis = 0; for (int i = v; i != rt; i = fa[i])S[top--] = i, sum += dis[i] - dis[fa[i]]; S[1] = rt; ++nn; top = dep[v] - dep[rt] + 1; len[nn] = sum; for (int i = 1; i <= top; i++) { int D = min(Dis, sum - Dis); add_edge(nn, S[i], D); zn[S[i]] = (D == Dis); Dis += dis[S[i + 1]] - dis[S[i]]; } } void Tar(int u, int _fa) { dfn[u] = low[u] = ++cnt; fa[u] = _fa; dep[u] = dep[_fa] + 1; for (int i = 0; i < (int)gg[u].size(); i++) { int v = gg[u][i].v, w = gg[u][i].w; if (v == _fa)continue; if (!dfn[v]) { dis[v] = dis[u] + w; Tar(v, u); low[u] = min(low[u], low[v]); } else low[u] = min(low[u], dfn[v]); if (dfn[u] < low[v]) { add_edge(u, v, w); } } for (int i = 0; i < (int)gg[u].size(); i++) { int v = gg[u][i].v, w = gg[u][i].w; if (v == _fa)continue; if (fa[v] != u && dfn[u] < dfn[v]) { solve_cir(u, v, w); } } } int ffa[maxn], sz[maxn], son[maxn], topf[maxn], dept[maxn]; int clk, val[maxn]; void dfs1(int u, int _fa) { ffa[u] = _fa; sz[u] = 1; dept[u] = dept[_fa] + 1; for (int i = 0; i < (int)G[u].size(); i++) { int v = G[u][i].v, w = G[u][i].w; if (v == _fa)continue; dis[v] = dis[u] + w; dfs1(v, u); sz[u] += sz[v]; if (sz[v] > sz[son[u]])son[u] = v; } } void dfs2(int u, int topfa) { topf[u] = topfa; dfn[u] = ++clk; val[clk] = u; if (!son[u])return; dfs2(son[u], topfa); for (int i = 0; i < (int)G[u].size(); i++) { int v = G[u][i].v; if (v == ffa[u] || v == son[u])continue; dfs2(v, v); } } int LCA(int u, int v) { while (topf[u] != topf[v]) dept[topf[u]] < dept[topf[v]] ? v = ffa[topf[v]] : u = ffa[topf[u]]; return dept[u] < dept[v] ? u : v; } int jp(int u, int lca) { int res; while (topf[u] != topf[lca]) { res = topf[u], u = ffa[topf[u]]; } return u == lca ? res : val[dfn[lca] + 1]; } int query(int u, int v) { int lca = LCA(u, v); if (lca <= n)return dis[u] + dis[v] - 2 * dis[lca]; int uu = jp(u, lca), vv = jp(v, lca); int d1 = dis[uu] - dis[lca], d2 = dis[vv] - dis[lca]; if (!zn[uu])d1 = len[lca] - d1; if (!zn[vv])d2 = len[lca] - d2; return dis[u] - dis[uu] + dis[v] - dis[vv] + min(abs(d1 - d2), len[lca] - abs(d1 - d2)); } int main() { scanf("%d%d%d", &n, &m, &Q); nn = n; for (int i = 0; i < m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); gg[u].push_back((edge) { v, w }); gg[v].push_back((edge) { u, w }); } Tar(1, 0); dis[1] = 0; dfs1(1, 0); dfs2(1, 1); while (Q--) { int u, v; scanf("%d%d", &u, &v); printf("%d\n", query(u, v)); } return 0; }
|