1 条题解
-
0
自动搬运
来自洛谷,原作者为

Acerkaio
物以类聚,鸟以群分搬运于
2025-08-24 21:37:27,当前版本为作者最后更新于2023-03-07 20:26:31,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
思路:
易知:此题在同一个边双连通分量中的每一条边都可以走一遍,我们遍可以将一个边双连通分量,缩成一个点,这个点的点权 便是该边双连通分量边权和。
缩完之后,我们剩下的边都是割边,便是一颗树,那么 到 只会有一个简单路径,便是新图的 到 , 是 所在的边双中的代表元素,即为 到 的边权和加上 到 的边权和,我们可以维护一个从根节点到每个点的边权和 那么答案即为
$w2_x + w2_y - 2 \times w2_{lca_{col_s, col_t}} + w1_{lca_{col_s, col_t}}$
CODE:
#include <bits/stdc++.h> using namespace std; const int _ = 1e6; int head[_], tot = 1; struct NODE { int x, y, edge, next; } edge[_ << 1]; void add(int u, int v, int ed) { tot++; edge[tot].x = u; edge[tot].y = v; edge[tot].edge = ed; edge[tot].next = head[u]; head[u] = tot; } int head1[_], thoth = 1; struct ND { int x, y, edge, next; } edge1[_ << 1]; void add1(int u, int v, int ed) { thoth++; edge1[thoth].x = u; edge1[thoth].y = v; edge1[thoth].edge = ed; edge1[thoth].next = head1[u]; head1[u] = thoth; } int dfn[_], low[_], NOD, cut[_], w1[_], w2[_]; int col[_]; stack <int> lxq; void Tarjan(int u, int ed) { dfn[u] = low[u] = ++NOD; lxq.push(u); for (int i = head[u], v; v = edge[i].y, i; i = edge[i].next) { if (!dfn[v]) { Tarjan(v, i); if (dfn[u] < low[v]) { cut[i] = cut[i ^ 1] = 1; } low[u] = min(low[u], low[v]); } else { if (i != (ed ^ 1)) { low[u] = min(low[u], dfn[v]); } } } if (dfn[u] == low[u]) { while (lxq.top() != u) { col[lxq.top()] = u; lxq.pop(); } col[lxq.top()] = u; lxq.pop(); } } /*po*/ int fa[_], Hson[_], Dep[_], Size[_], Top[_], seg[_], rev[_], DFNtot = 0; void Podfs1(int p, int f, int deg) { fa[p] = f; Dep[p] = Dep[f] + 1; Size[p] = 1; w2[p] += w1[p] + deg; for (int i = head1[p]; i; i = edge1[i].next) { int v = edge1[i].y; if (v == f) continue; Podfs1(v, p, w2[p] + edge1[i].edge); Size[p] += Size[v]; if (Size[v] > Size[Hson[p]]) Hson[p] = v; } } void Podfs2(int p, int top) { ++DFNtot; Top[p] = top; seg[p] = DFNtot; rev[DFNtot] = p; if (Hson[p]) Podfs2(Hson[p], top); for (int i = head1[p]; i; i = edge1[i].next) { int v = edge1[i].y; if (v == fa[p]) continue; if (Hson[p] != v) Podfs2(v, v); } } int LCA(int u, int v) { int fu = Top[u], fv = Top[v]; while (fu != fv) { // cout << u << ' ' << v << '\n'; if (Dep[fu] < Dep[fv]) swap(fu,fv), swap(u, v); u = fa[fu], fu = Top[u]; } return Dep[u] < Dep[v] ? u : v; } signed main() { int n, m; cin >> n >> m; for (int i = 1; i <= m; i++) { int x, y, z; cin >> x >> y >> z; add(x, y, z); add(y, x, z); } for (int i = 1; i <= n; i++) if (!dfn[i]) Tarjan(i, 0); for (int i = 1; i <= tot; i++) { int u = col[edge[i].x], v = col[edge[i].y], w = edge[i].edge; if (u == v) { w1[u] += w; } else { add1(u, v, w); } } Podfs1(1, 1, 0); Podfs2(1, 1); int q; cin >> q; for (int i = 1; i <= q; i++) { int x, y, lca; cin >> x >> y; //cout << x << ' ' << y << '\n'; x = col[x], y = col[y]; // cout << x << ' ' << y; lca = LCA(x, y); if (w2[x] + w2[y] - 2 * w2[lca] + w1[lca] > 0) cout << "YES\n"; else cout << "NO\n"; } return 0; }
- 1
信息
- ID
- 1813
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者