樹的重心 樹的直徑

2021-10-02 12:21:49 字數 2946 閱讀 3268

樹的重心

樹的重心定義為:找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心,刪去重心後,生成的多棵樹盡可能平衡.

實際上樹的重心在樹的點分治中有重要的作用, 可以避免n^2的極端複雜度(從退化鏈的一端出發),保證nlogn的複雜度, 利用樹型dp可以很好地求樹的重心.求樹的重心

模板:

//樹的重心可能有兩個

//做法:從任意點出發,dfs遍歷整棵樹,在回溯的過程中,維護每個子樹的結點個數以及這個結點的最大子樹節點個數

#include

#include

#include

#include

#include

using namespace std;

const

int manx=

5e4+10;

const

int inf=

1e9;

int head[manx]

,dp[manx][2

],vs[manx]

;//0表示子樹結點個數,1表示最大子樹結點個數

int n,cou=

0,ans=inf,root1=

0,root2=

0,flag=0;

struct node

edge[manx<<1]

;void

add(

int s,

int e)

; head[s]

=cou++;}

void

dfs(

int root)

} dp[root][0

]++; dp[root][1

]=max(dp[root][1

],n-dp[root][0

]);if

(dp[root][1

]else

if(dp[root][1

]==ans)

}int

main()

dfs(1)

;if(!flag)

printf

("%d\n"

,root1)

;else

printf

("%d %d\n"

,min

(root1,root2)

,max

(root1,root2));

}

樹的直徑
定義:

一棵樹的直徑就是這棵樹上存在的最長路徑。

求法1:

兩次dfs或bfs。第一次任意選乙個點進行dfs(bfs)找到離它最遠的點,此點就是最長路的乙個端點,再以此點進行dfs(bfs),找到離它最遠的點,此點就是最長路的另乙個端點,於是就找到了樹的直徑。樹的直徑求法及證明

求法2:

設定狀態dp[u][2]

dp[u][0]表示距離u的最長距離,dp[u][1]表示距離u的次長距離(與最長距離的節點不在同一顆子樹上)然後狀態方程為

ans=(ans,dp[u][0]+dp[u][1])ans為樹的直徑答案樹的直徑(樹形dp)

另外數的直徑這裡有乙個引理,樹的所有直徑擁有相同的中點求法二有兩種寫法,但都在再回溯時維護最長鏈:

模板:1、遞迴出去時維護每個點深度,回溯時維護最大深度

void

dfs(

int now,

int fa)if(

!flag)

}

2、只在回溯時維護最遠和次遠距離(離當前結點最遠/次遠的葉子結點)

void

dfs(

int now,

int fa)

else

if(dp[now][1

]]+nlen)

dp[now][1

]=dp[net][0

]+nlen;

} ans=

max(ans,dp[now][0

]+dp[now][1

]);}

整體**:

#include

#include

#include

#include

using namespace std;

const

int manx=

4e4+10;

const

int inf=

0x3fffffff

;int n,m,cou,ans;

int deep[manx]

,dp[manx]

,head[manx]

;//dp存最大深度

struct node

}edge[manx<<1]

;void

add(

int s,

int e,

int len)

void

init()

void

dfs(

int now,

int fa)if(

!flag)

}int

main()

deep[1]

=0;dfs(1

,0);

printf

("%d\n"

,ans)

;return0;

}

例題1:

兩次dfs解法:f. three paths on a tree

例題2:樹的直徑+貪心)

例題3:樹上子鏈: 附:

樹的直徑 樹的重心

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

求樹的重心 樹的直徑

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

樹的直徑與重心

樹的直徑,指樹上最長的不重複經過同乙個點的路徑。方法 先從任意一點p pp出發,找離它最遠的點q qq,再從點q qq出發,找離它最遠的點w ww,w ww到q qq的距離就是的直徑 具體實現可以使用兩次dfs dfsdf s。演算法證明 反證法 include using namespace st...