AcWing846 樹的重心(C 演算法)

2021-10-24 17:38:27 字數 1268 閱讀 3321

1、題目:

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

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

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

輸入格式

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

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

輸出格式

輸出乙個整數m,表示重心的所有的子樹中最大的子樹的結點數目。

資料範圍

1≤n≤105

輸入樣例

91 2

1 71 4

2 82 5

4 33 9

4 6輸出樣例:

42、基本思想:

用深度搜尋,假設有n個節點。記錄每乙個節點,以u為例,先以u為根節點,遍歷它的每個子樹(假設子樹編號為1、2、3)期間記錄u樹的節點個數和sum(包括根),記錄含有節點個數最多的那個子樹(假設是1號子樹),最後比較這個1號子樹和(n - sum)的大小,選出最小值。以此類推遍歷整個樹中其他節點。

3、c ++ **如下(該**引用acwing****)

#include

#include

#include

using

namespace std;

const

int n =

100010

;int n;

int h[n]

, e[n *2]

, ne[n *2]

, idx;

//因為是無向邊所以每條邊會存兩次,所以n*2.

int ans = n;

//最終輸出答案

bool st[n]

;//記錄遍歷過的點

void

add(

int a,

int b)

intdfs

(int u)

size =

max(size, n - sum)

;//比較以u為根最大聯通子圖節點數與去掉以u為根的所有節點,看誰最大

ans =

min(ans, size)

;return sum;

}int

main()

dfs(1)

;//從1~n任意乙個數開始都可以。

cout << ans;

return0;

}

AcWing 846 樹的重心

大佬的題解 題目鏈結 這道題給的標籤竟然是 樹與圖的深度優先遍歷 這是神馬玩意,然後我點進去看了一下,果然還是沒有思路,然後看了y總,如願以償,y總yyds,我看懂了,然後我就認真再看了一遍題。我覺得好像是求子樹問題,然後我就有了思路。大佬的題解其實講的很清楚,最主要的是靠自己的想象,最關鍵的幾個變...

ACWing846 樹的重心

dfs,一次遍歷,求出每個結點去除該點後的最大連通塊的個數,同時更新ans 全域性變數存放最終結果 1 include2 include3 include4 using namespace std 56 const int n 100010 7 int h n e n 2 ne n 2 idx 樹為...

AcWing 846 樹的重心

給定一顆樹,樹中包含n個結點 編號1 n 和n 1條無向邊。請你找到樹的重心,並輸出將重心刪除後,剩餘各個連通塊中點數的最大值。重心定義 重心是指樹中的乙個結點,如果將這個點刪除後,剩餘各個連通塊中點數的最大值最小,那麼這個節點被稱為樹的重心。輸入格式 第一行包含整數n,表示樹的結點數。接下來n 1...