學習筆記 樹的重心

2021-10-19 06:53:58 字數 1646 閱讀 3647

給定一顆樹,樹中包含n個結點(編號1~n)和n-1條無向邊。

請你找到樹的重心,並輸出將重心刪除後,剩餘各個連通塊中點數的最大值。

重心定義:重心是指樹中的乙個結點,如果將這個點刪除後,剩餘各個連通塊中點數的最大值最小,那麼這個節點被稱為樹的重心。

輸入格式

第一行包含整數n,表示樹的結點數。

接下來n-1行,每行包含兩個整數a和b,表示點a和點b之間存在一條邊。

輸出格式

輸出乙個整數m,表示將重心刪除後,剩餘各個連通塊中點數的最大值。

思路:列舉每乙個點被刪除後的情況,計算聯通塊中的點數,在樹中刪除乙個點後,聯通塊的情況:點u的每乙個子樹是乙個聯通塊,同時除了剩餘的除了點u及其子樹外是另乙個聯通塊

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define ull unsigned long long

#define up_b upper_bound

#define low_b lower_bound

#define m_p make_pair

#define mem(a) memset(a,0,sizeof(a))

#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

#define inf 0x3f3f3f3f

#define endl "\n"

#include

using

namespace std;

inline ll read()

while

('0'

<=ch&&ch<=

'9') x=x*

10+ch-

'0', ch=

getchar()

;return f*x;

}const

int n =

1e5+5;

int n;

bool vis[n]

;struct nodeedge[

2*n]

;int head[n]

,idx;

void

add(

int u,

int v)

; head[u]

=idx++;}

int ans=inf;

intdfs

(int u)

//dfs的返回值是以點u為為根節點的子樹的大小

res=

max(res,n-sum)

;//除了點u及其子樹外的另乙個聯通塊

ans=

min(res,ans)

;//最終答案在所有res中取乙個最小值

return sum;

}int

main()

dfs(1)

;//遍歷整個樹,從那個點開始都可以

cout

}

學習筆記 樹的重心

樹的重心 對於一顆n個結點的無根樹,找到乙個點,使得把樹變成以該點為跟的有根樹時,最大子樹的結點數最小,就是說如果刪除這個點後,所形成的森林中,最大的樹的結點數最小。性質 1 樹中所有結點到某個點的距離和中,到重心的距離和是最小的,如果有兩個距離和,則他們的距離和一樣。2 把兩棵樹通過一條邊相連,新...

樹的直徑與重心學習筆記

此文為完成任務所設,可能不易懂,能看懂就將就著看吧 樹的定義 不存在環且聯通的圖。樹的直徑 樹中的最長鏈 樹的重心 為乙個點,以此點為根,最大子樹的大小最小。樹的直徑求法分兩種 兩次 dfs bfs 與樹形 dp 首先講好理解點的樹形 dp 其實很簡單,每個節點維護子樹到這個點的最長鏈和次長鏈。對於...

樹的直徑 樹的重心與樹的點分治學習筆記

樹的直徑是指樹上的最長簡單路。任選一點w為起點,對樹進行搜尋,找出離w最遠的點u。以u為起點,再進行搜尋,找出離u最遠的點v。則u到v的路徑長度即為樹的直徑。簡單證明 如果w在直徑上,那麼u一定是直徑的乙個端點。反證 若u不是端點,設直徑的兩端為s與t,則dist w,u dist u,t 且dis...