CSP S2019 D2T3 樹的重心

2021-09-29 21:27:45 字數 3362 閱讀 3013

小簡單正在學習離散數學,今天的內容是圖論基礎,在課上他做了如下兩條筆記:

乙個大小為 n

nn 的樹由 n

nn 個結點與 n−1

n − 1

n−1 條無向邊構成,且滿足任意兩個結點間有且僅有一條簡單路徑。在樹中刪去乙個結點及與它關聯的邊,樹將**為若干個子樹;而在樹中刪去一條邊(保留關聯結點,下同),樹將**為恰好兩個子樹。

對於乙個大小為 n

nn 的樹與任意乙個樹中結點 c

cc,稱 c

cc 是該樹的重心當且僅當在樹中刪去 c

cc 及與它關聯的邊後,**出的所有子樹的大小均不超過 ⌊n2

⌋\lfloor \frac \rfloor

⌊2n​

⌋(其中 ⌊x⌋

\lfloor x \rfloor

⌊x⌋ 是下取整函式)。對於包含至少乙個結點的樹,它的重心只可能有 1

11 或 2

22 個。

課後老師給出了乙個大小為 n

nn 的樹 s

ss,樹中結點從 1∼n

1 \sim n

1∼n 編號。小簡單的課後作業是求出 s

ss 單獨刪去每條邊後,**出的兩個子樹的重心編號和之和。即:

∑ (u

,v)∈

e(∑1

≤x≤n

且x號點

是su′

的重心x

+∑1≤

y≤n且

y號點是

sv′的

重心y)

\sum_ \left( \sum_ x + \sum_ y \right)

(u,v)∈

e∑​⎝

⎜⎛​且

x號點是

su′​

的重心1

≤x≤n

​∑​x

+且y號

點是sv

′​的重

心1≤y

≤n​∑

​y⎠⎟

⎞​​上式中,e

ee 表示樹 s

ss 的邊集,(u,

v)(u,v)

(u,v

) 表示一條連線 u

uu 號點和 v

vv 號點的邊。su′

s'_u

su′​

​ 與 sv′

s'_v

sv′​

​ 分別表示樹 s

ss 刪去邊 (u,

v)(u,v)

(u,v

) 後,u

uu 號點與 v

vv 號點所在的被**出的子樹。

小簡單覺得作業並不簡單,只好向你求助,請你教教他。

40 分的做法是列舉一條邊,將它斷掉後再暴力求出兩邊的重心。

結論:重心必須在以根節點為起點的重鏈上。

證明:不會。。。

然後我們可以利用這個結論,列舉每乙個點,統計每個點在刪掉邊後對答案的貢獻次數即可。

當我們**出一棵完整的子樹時,就像這樣:

對於以 v

vv 為根的子樹的這部分,根據結論,我們沿著以 v

vv 為起點的重鏈往下跳就可以了。

對於剩餘的部分,我們考慮換根。將剩餘的部分提成以 u

uu 為根的樹,然後暴力修改重兒子和重鏈即可。

我們可以用倍增來優化尋找重心的這一部分。

#include

#include

using

namespace std;

const

int maxn =

300000

;const

int maxlog =19;

typedef

long

long ll;

#ifdef loacl

bool ___;

#endif

struct edge

;edge pool[maxn *2+

5];edge *g[maxn +5]

,*ecnt;

inline

void

addedge

(int u,

int v)

int n;

int siz[maxn +5]

;int mxson[maxn +5]

, mx2son[maxn +5]

;ll ans;

int s[maxn +1]

[maxlog +2]

;int f[maxn +5]

;inline

void

clear()

inline

void

modify

(int u)

void

predfs

(int u,

int fa)

else

if(siz[v]

> siz[mx2son[u]])

mx2son[u]

= v;

} s[u][0

]= mxson[u]

;modify

(u);

}inline

void

calc

(int u)

void

dfs(

int u,

int fa)

else

if(n - siz[u]

> siz[mx2son[u]])

for(edge *p = g[u]

; p !=

null

; p = p-

>nxt)

if(flag ==1)

else

if(flag ==

2) mx2son[u]

= t1;

s[u][0

]= mxson[u]

;modify

(u);

}#ifdef loacl

bool ____;

#endif

intmain()

predfs(1

,0);

dfs(1,

0);printf

("%lld\n"

, ans);}

#ifdef loacl

printf

("%.2f\n",(

&____ -

&___)

/1048576.0);

#endif

return0;

}

CSP S2019 D1T3 樹上的數

給定乙個大小為 n nn 的樹,它共有 n nn 個結點與 n 1 n 1 n 1 條邊,結點從 1 n 1 sim n 1 n 編號。初始時每個結點上都有乙個 1 n 1 sim n 1 n 的數字,且每個 1 n 1 sim n 1 n 的數字都只在恰好乙個結點上出現。接下來你需要進行恰好 n ...

CSP 2019 Day2 T3 樹的重心

題目鏈結 首先有這樣乙個結論 一顆樹的重心要麼是根節點要麼在它重兒子的子樹裡 這個結論十分顯然在這裡就不證明了 於是我們第一遍 dfs 求出以1節點為根時每個點的重兒子和次重兒子 因為會斷掉重兒子的這條邊 以及 pr 表示從 u 節點開始每次沿重兒子跳 2 i 步跳到的點的位置 對於第二次 dfs ...

NOIp2017D2T3 列隊(線段樹)

sylvia是乙個熱愛學習的女 孩子。前段時間,sylvia參加了學校的軍訓。眾所周知,軍訓的時候需要站方陣。sylvia 所在的方陣中有 n mn times mn m 名學生,方陣的行數為 nnn 列數為 mmm 為了便於管理,教官在訓練開始時,按照從前到後,從左到右的順序給方陣中 的學生從 1...