修马路

问题描述

⼩迟⽣活的城市是⼀棵树(树指的是⼀个含有 n 个节点以及 n1 条边的⽆向连通图),节点编号从 1n,每条边拥有⼀个权值 value,表⽰通过这条边的时候你需要交纳的⾦钱(注意,有可能这个值为负数,也就是说你经过这条边的时候你可以赚钱)

⼩迟是⼀个杰出的马路⼯,他居住在节点 s,他能够选择任意⼀个节点m,并将从节点 s 到节点 m 的简单路径(简单路径指的是不经过同⼀个节点两次)上的所有边的权值都修改为 0.

现在⼩迟获得 q 个请求,每个请求都是以 a,b 的形式给出,表⽰⼩迟的好朋友⼩早希望从节点 a ⾛简单路径到节点 b,⼩迟希望能最⼩化⼩早需要缴纳的钱。

需要注意的是,⼩迟获得的这 q 个请求是相互独⽴的,也就是说您只需要对于每⼀个请求,决定⼩迟的⼀个修路⽅案,使得⼩早需要缴纳的钱尽可能的少。

输入格式

输⼊⽂件名为 road.in。

第⼀⾏三个正整数为 n,q,s

接下来 n1 ⾏,每⾏三个整数 xyz, 表⽰有⼀条边 (x,y)valuez

接下来 q ⾏,每⾏两个正整数 a,b,表⽰请求。

输出格式

输出⽂件名为 road.out。

Q ⾏,每⾏⼀个整数,表⽰需要缴纳的最少的钱。

样例输入

Copy
3 2 1 1 2 1 2 3 1 1 2 1 3

样例输出

Copy
0 0

样例解释

对于第⼀次询问 1,2, ⼩迟可以修从 12 的路,从⽽使得⼩早不需要缴纳⾦钱;

对于第⼆次询问 1,3, ⼩迟可以修从 13 的路,从⽽使得⼩早不需要缴纳⾦钱。

数据规模及约定

对于 30% 的数据,n1000,q1000

对于 100% 的数据,1n,q200000,1x,yn,|z|1000

题目分析

题目给的是一颗无根树,如果我们以小迟的家作为根的话,这个问题相当于你可以删去根到任意节点的权值, 使得 ab 花费最少

看到树上的简单路径,就知道这道题一定考察 LCA

算法一: 在树上倍增求LCA的基础上, 同时维护倍增的最大和, 复杂度 nlogn, 然而我考场上想出来没Debug出来

算法二:考虑链上问题, 即求链上最大值。在树链剖分上线段树维护最大值就好了, 复杂度 nlog2n(远远无法达到理论上界)

Copy
#include <cstdio> int read() { int x = 0, ch = getchar(), f = 0; for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = 1; for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48); return f ? -x : x; } int max(const int &x, const int &y) { return x > y ? x : y; } #define rep(i, s, t) for (int i = (int)(s); i <= (int)(t); ++ i) const int maxn = 2e5 + 10; int ver[maxn << 1], Next[maxn << 1], head[maxn], edge[maxn << 1], tot; int sz[maxn], dep[maxn], son[maxn], fa[maxn], pos[maxn], tid[maxn], a[maxn], dfn, top[maxn]; int n, m, root; inline void addline(int x, int y, int z) { ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot; } inline void swap(int &x, int &y) { int t = y; y = x; x = t; } struct SegmentTree { int l, r, val; SegmentTree() { val = -1e9; l = r = 0; } }tree[maxn << 2]; inline void build(int k, int l, int r) { tree[k].l = l, tree[k].r = r; if (l == r) { tree[k].val = a[pos[l]]; return; } int mid = (l + r) >> 1; build(k << 1, l, mid); build(k << 1 | 1, mid + 1, r); tree[k].val = max(tree[k << 1].val, tree[k << 1 | 1].val); } int query(int k, int l, int r) { if (tree[k].l == l && tree[k].r == r) { return tree[k].val; } int mid = (tree[k].l + tree[k].r) >> 1; if (mid >= r) { return query(k << 1, l, r); } else if (mid < l) { return query(k << 1 | 1, l, r); } else { return max(query(k << 1, l, mid), query(k << 1 | 1, mid + 1, r)); } } inline void dfs1(int x, int f, int d, int val) { sz[x] = 1, fa[x] = f, dep[x] = d, a[x] = val; for (int i = head[x], y; i; i = Next[i]) { if ((y = ver[i]) == f) continue; dfs1(y, x, d + 1, val + edge[i]); sz[x] += sz[y]; if (sz[y] > sz[son[x]]) son[x] = y; } } inline void dfs2(int x, int rt) { top[x] = rt, pos[tid[x] = ++dfn] = x; if (son[x]) dfs2(son[x], rt); for (int i = head[x], y; i; i = Next[i]) { if ((y = ver[i]) != fa[x] && y != son[x]) dfs2(y, y); } } int lca(int x, int y) { if (top[x] == top[y]) return dep[x] < dep[y] ? x : y; while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); x = fa[top[x]]; } return dep[x] < dep[y] ? x : y; } inline void Pre() { dfs1(root, root, 0, 0), dfs2(root, root), build(1, 1, n); } int jump(int f, int t) { if (top[f] == top[t]) { return query(1, tid[t], tid[f]); } int ans = -1e9; while (top[f] != top[t]) { ans = max(ans, query(1, tid[top[f]], tid[f])); f = fa[top[f]]; } ans = max(ans, query(1, tid[t], tid[f])); return ans; } int query(int x, int y) { int Lca = lca(x, y), aa = jump(x, Lca) - a[Lca], ba = jump(y, Lca) - a[Lca]; int ans = a[x] + a[y] - 2 * a[Lca]; aa = max(aa, 0); ba = max(ba, 0); return ans - max(aa, ba); } int main() { n = read(), m = read(), root = read(); int x, y, z; rep(i, 1, n - 1) x = read(), y = read(), z = read(), addline(x, y, z), addline(y, x, z); Pre(); rep(i, 1, m) { x = read(), y = read(); printf("%d\n", query(x, y)); } }
posted @   AlessandroChen  阅读(374)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示