bool vis[N]; int far, S, T, fa[N], dis[N]; voiddfs(int u, int f) { fa[u] = f; if (dis[u] > dis[far]) far = u; for (auto nxt : E[u]) { int v = nxt.first, w = nxt.second; if (v == f || vis[v]) continue; dis[v] = dis[u] + w; dfs(v, u); } }
int n;
intmain() { scanf("%d", &n); for (int i = 1; i < n; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); E[u].push_back(make_pair(v, w)); E[v].push_back(make_pair(u, w)); } dis[1] = 0, dfs(1, 0), S = far; dis[S] = 0, dfs(S, 0), T = far; printf("%d %d\n", S, T); return0; }
int dis[N]; bool vis[N]; inlineintbfs(int s) { queue<int> Q; memset(dis, 0, sizeof(dis)); memset(vis, false, sizeof(vis)); int far = 0; Q.push(s); vis[s] = true; while (!Q.empty()) { int u = Q.front(); Q.pop(); for (auto nxt : E[u]) { int v = nxt.first, w = nxt.second; if (vis[v]) continue; vis[v] = true; dis[v] = dis[u] + w; Q.push(v); if (dis[v] > dis[far]) far = v; } } return far; }
intmain() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); E[u].push_back(make_pair(v, w)); E[v].push_back(make_pair(u, w)); } int S = bfs(1); int T = bfs(S); printf("%d %d\n", S, T); return0; }
int f[N][F], dep[N]; voiddfs(int u, int fa) { dep[u] = dep[fa] + 1; f[u][0] = fa; for (int i = 1; i < F; i++) { f[u][i] = f[f[u][i - 1]][i - 1]; } for (int v : E[u]) { if (v == fa) continue; dfs(v, u); } }
inlineintLCA(int u, int v) { if (dep[u] < dep[v]) swap(u, v); for (int i = F - 1; i >= 0; i--) { if (dep[f[u][i]] >= dep[v]) { u = f[u][i]; } } if (u == v) return u; for (int i = F - 1; i >= 0; i--) { if (f[u][i] ^ f[v][i]) { u = f[u][i]; v = f[v][i]; } } return f[u][0]; }
intmain() { scanf("%d%d%d", &n, &m, &s); for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); E[x].push_back(y); E[y].push_back(x); } dfs(s, 0); while (m--) { int a, b; scanf("%d%d", &a, &b); printf("%d\n", LCA(a, b)); } return0; }
int fat[N], siz[N], dep[N], son[N]; voiddfs1(int u, int fa) { fat[u] = fa; siz[u] = 1; dep[u] = dep[fa] + 1; for (int v : E[u]) { if (v == fa) continue; dfs1(v, u); siz[u] += siz[v]; if (siz[v] > siz[son[u]]) son[u] = v; } }
int dfn[N], idx[N], top[N], Index; voiddfs2(int u, int Top) { dfn[u] = ++Index; idx[Index] = u; top[u] = Top; if (son[u]) { dfs2(son[u], Top); for (int v : E[u]) { if (v == fat[u] || v == son[u]) continue; dfs2(v, v); } } }
inlineintLCA(int u, int v) { while (top[u] != top[v]) { if (dep[top[u]] < dep[top[v]]) swap(u, v); u = fat[top[u]]; } return dep[u] < dep[v] ? u : v; }
intmain() { scanf("%d%d%d", &n, &m, &s); for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); E[x].push_back(y); E[y].push_back(x); } dfs1(s, 0); dfs2(s, 0); while (m--) { int a, b; scanf("%d%d", &a, &b); printf("%d\n", LCA(a, b)); } return0; }
int fa[N]; intfind(int x) { return fa[x] == x ? fa[x] : fa[x] = find(fa[x]); }
bool vis[N]; int ans[N]; voiddfs(int u) { fa[u] = u; vis[u] = true; for (int v : E[u]) { if (vis[v]) continue; dfs(v); fa[v] = u; } for (auto cur : Q[u]) if (vis[cur.first]) ans[cur.second] = find(cur.first); }
intmain() { scanf("%d%d%d", &n, &m, &s); for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); E[x].push_back(y); E[y].push_back(x); } for (int i = 1; i <= m; i++) { int a, b; scanf("%d%d", &a, &b); Q[a].push_back(make_pair(b, i)); Q[b].push_back(make_pair(a, i)); } dfs(s); for (int i = 1; i <= m; i++) printf("%d\n", ans[i]); return0; }
2.3 应用
2.3.1 树上差分
问题描述
对于 n 个节点的树,进行 k 次修改操作,每次将 s 到 t 的路径上的点权增加 x,查询每个点的最终值.
思路
对于每一次修改的路径 $ s \to t $ 我们可以把将其拆分为 $ s \to LCA(s, t) \to t$ 两段,考虑到这是一个区间修改单点查询的问题,我们可以用差分思想将修改操作进行转换:
int f[N][F], dep[N]; voiddfs(int u, int fa) { dep[u] = dep[fa] + 1; f[u][0] = fa; for (int i = 1; i < F; i++) { f[u][i] = f[f[u][i - 1]][i - 1]; } for (int v : E[u]) { if (v == fa) continue; dfs(v, u); } }
inlineintLCA(int u, int v) { if (dep[u] < dep[v]) swap(u, v); for (int i = F - 1; i >= 0; i--) { if (dep[f[u][i]] >= dep[v]) { u = f[u][i]; } } if (u == v) return u; for (int i = F - 1; i >= 0; i--) { if (f[u][i] ^ f[v][i]) { u = f[u][i]; v = f[v][i]; } } return f[u][0]; }
int d[N], val[N]; voiddfs_(int u, int fa) { val[u] = d[u]; for (int v : E[u]) { if (v == fa) continue; dfs_(v, u); val[u] += val[v]; } }
intmain() { scanf("%d%d", &n, &k); for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); E[x].push_back(y); E[y].push_back(x); } dfs(1, 0); while (k--) { int s, t, x; scanf("%d%d", &s, &t, &x); int u = LCA(s, t); d[s] += x, d[t] += x; d[f[u][0]] -= x, d[u] -= x; } dfs_(1, 0); for (int i = 1; i <= n; i++) printf("%d%c", ans[i], i == n ? '\n' : ' '); return0; }