樹的直徑與重心

2021-10-21 15:06:10 字數 1587 閱讀 1500

樹的直徑,指樹上最長的不重複經過同乙個點的路徑。

方法:先從任意一點p

pp出發,找離它最遠的點q

qq,再從點q

qq出發,找離它最遠的點w

ww,w

ww到q

qq的距離就是的直徑

具體實現可以使用兩次dfs

dfsdf

s。演算法證明(反證法)

#include

using

namespace std;

const

int maxn =

1e5+99;

struct edge

e[maxn]

;int n, m, t, p, ans;

int d[maxn]

, head[maxn]

, vis[maxn]

;void

add(

int x,

int y,

int z)

//建圖

void

dfs(

int x)

//dfs搜尋

vis[x]=1

;for

(int i = head[x]

; i; i = e[i]

.next)

}void

find

(int x)

intmain()

find

(n);

//也可以隨便取乙個點

find

(p);

printf

("%d"

, ans)

;return0;

}

樹的重心定義為樹的某個節點,當去掉該節點後,樹的各個連通分量中,節點數最多的連通

分量其節點數達到最小值。

設p[i]為去掉i點與它相連的邊之後,圖中所存在的子樹中的節點數最大的值。

將p陣列比較,最小的就是樹的重心。

#include

using

namespace std;

const

int n =

1e6+50;

int n, siz[n]

, max[n]

, ans, cnt;

vector<

int> d[n]

;inline

voiddp(

int r,

int f)

max[r]

=max

(max[r]

, n - siz[r]);

if(max[r]

< max[ans]

) ans = r;

if(max[r]

== max[ans]

&& r < ans)

ans = r;

}signed

main()

dp(1,

0);printf

("%d %d\n"

, ans, max[ans]);

}}

樹的重心 樹的直徑

樹的重心 樹的重心定義為 找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心,刪去重心後,生成的多棵樹盡可能平衡.實際上樹的重心在樹的點分治中有重要的作用,可以避免n 2的極端複雜度 從退化鏈的一端出發 保證nlogn的複雜度,利用樹型dp可以很好地求樹的重心.求樹的重心 模...

樹的直徑 樹的重心

樹的直徑 定義 那麼樹上最遠的兩個點,他們之間的距離,就被稱之為樹的直徑。樹的直徑的性質 1.直徑兩端點一定是兩個葉子節點。2.距離任意點最遠的點一定是直徑的乙個端點,這個基於貪心求直徑方法的正確性 可以得出。3.對於兩棵樹,如果第一棵樹直徑兩端點為 u,v 第二棵樹直徑兩端點為 x,y 用條邊將兩...

求樹的重心 樹的直徑

樹的重心 樹的重心是指樹上一點,去掉後最大子樹可以取得最小值的點。求解方法 樹的重心定義 去掉該點後最大子樹大小不超過n 2。重心為1 樹的直徑指樹上最遠兩點的距離 方法 先隨便找個點,找到離他最遠的點,再在那個最遠的點上找一次最遠的點,這兩個點之間的距離就是直徑。include define ma...