樹的直徑,指樹上最長的不重複經過同乙個點的路徑。
方法:先從任意一點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...