小簡單正在學習離散數學,今天的內容是圖論基礎,在課上他做了如下兩條筆記:
乙個大小為 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...