給定一顆樹,樹中包含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...