树的直径

Posted TURNINING

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树的直径相关的知识,希望对你有一定的参考价值。

定义:图中所有最短路径的最大值即为「直径」。

做法:两次dfs O(n)

重要性质:树上任意一点的所能达到的最长距离的另一端点,必定是直径两端点之一。故求最长距离直接取两个直径端点到它的距离的max就行了。

HDU 2196

#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;
}

以上是关于树的直径的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的直径-leetocde543

树的直径

543. 二叉树的直径

P2195 HXY造公园(并查集+树的直径)

2227 邮票--FUoj(链接表+树的直径)

BDFZOI 树的直径