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

yingxi
没咋 || 最后在线时间:2025年8月21日10时55分搬运于
2025-08-24 23:02:58,当前版本为作者最后更新于2025-05-14 15:58:34,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目传送门
题意
给定一棵有 个节点的树,对于每个节点,都求出离他最远的节点离他的距离。
思路
-
暴力:以每个点为起点依次进行
dfs(i, 0),查看从 出发最多走多少步。 -
二次 dfs 法:第一次 dfs 从下往上搜,第二次 dfs 从上往下搜,具体见代码。
ACcode:
#include<bits/stdc++.h> #define int long long using namespace std; const int N = 1e4 + 5; vector<pair<int, int> > g[N]; int dis1[N], dis2[N]; //dis1表示子树的最长路, dis2表示子树的次长路 int f[N], son[N]; //son表示子树的最长路的节点编号, f表示子树外的最长路 int n; void dfs1(int u, int fa) { for (auto x : g[u]) { int v = x.first, w = x.second; if (v == fa) continue; dfs1(v, u); //回溯过程将子树的信息带回来更新u if (dis1[u] < dis1[v] + w) { dis2[u] = dis1[u]; //先更新次长路 dis1[u] = dis1[v] + w; son[u] = v; // 最长路先经过v } else if (dis2[u] < dis1[v] + w) dis2[u] = dis1[v] + w; } return ; } void dfs2(int u, int fa) { for (auto x : g[u]) { int v = x.first, w = x.second; if (v == fa) continue; //在递的过程中更新数据,父亲更新儿子 if (son[u] != v) //u的最长路不包含v, 可以直接用 f[v] = max(dis1[u], f[u]) + w; else f[v] = max(dis2[u], f[u]) + w; dfs2(v, u); } return ; } void solve() { for (int i = 1; i <= n; i++) g[i].clear(); //多测注意清空 memset(dis1, 0, sizeof dis1); memset(dis2, 0, sizeof dis2); memset(f, 0, sizeof f); for (int i = 2; i <= n; i++) { int u, v; cin >> u >> v; g[i].push_back({u, v}); g[u].push_back({i, v}); } dfs1(1, 0); //从下往上dfs dfs2(1, 0); //从上往下dfs for (int i = 1; i <= n; i++) cout << max(dis1[i], f[i]) << "\n"; return ; } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); while (cin >> n) solve(); return 0; } -
- 1
信息
- ID
- 10128
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- (无)
- 递交数
- 0
- 已通过
- 0
- 上传者