树的直径

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(edgev, c);
        g[v].emplace_back(edgei, 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;

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

树的直径

树的直径

树的直径概念及求解

树的直径与重心

树的直径与重心

树的直径问题模板及其原理