树的直径
Posted TURNINING
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树的直径相关的知识,希望对你有一定的参考价值。
定义:图中所有最短路径的最大值即为「直径」。
做法:两次dfs O(n)
重要性质:树上任意一点的所能达到的最长距离的另一端点,必定是直径两端点之一。故求最长距离直接取两个直径端点到它的距离的max就行了。
#include<bits/stdc++.h>
using namespace std;
#define lsn (u << 1)
#define rsn (u << 1 | 1)
#define mid (l + r >> 1)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<double, double> PD;
const int MAXN = 1e4 + 10;
const int MAX_LEN = 100000 + 10;
const int MAX_LOG_V = 22;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-7;
const ull B = 100000007;
struct edge { int to, cost; };
vector<edge> g[MAXN];
int n;
int d[MAXN], c;
int d1[MAXN], d2[MAXN];
void dfs(int u, int p, int *d) {
for(int i = 0; i < g[u].size(); i++) {
edge &e = g[u][i];
if(e.to == p) continue;
d[e.to] = d[u] + e.cost;
if(d[e.to] > d[c]) c = e.to;
dfs(e.to, u, d);
}
}
void solve() {
for(int i = 1; i <= n; i++) g[i].clear();
for(int i = 2; i <= n; i++) {
int v, c;
scanf("%d %d", &v, &c);
g[i].emplace_back(edge{v, c});
g[v].emplace_back(edge{i, c});
}
d[c = 1] = 0;
dfs(1, 0, d); d1[c] = 0;
dfs(c, 0, d1); d2[c] = 0;
dfs(c, 0, d2);
for(int i = 1; i <= n; i++) {
printf("%d\\n", max(d1[i], d2[i]));
}
}
int main() {
//ios::sync_with_stdio(false);
int t = 1; //scanf("%d", &t);
while(scanf("%d", &n) == 1) {
solve();
}
return 0;
}
以上是关于树的直径的主要内容,如果未能解决你的问题,请参考以下文章