同步
原題鏈結
簡要題意:
給定一棵樹,dx,
yd_
dx,y
為 x
xx 與 y
yy 距離(dx,
x=
0d_ = 0
dx,x=
0),選出兩個點 x,y
x,yx,
y,最小化:
∑ u∈
v(wu
×min(
disx
,u,d
isy,
u)
)\sum_ (w_u \times \min(dis_ , dis_))
u∈v∑(
wu×
min(di
sx,u
,di
sy,u
))這種水的樹形dp 黑題,沒幾個人做真是太可惜了
首先我們要明白這個式子是什麼意思。
min (
disx
,u,d
isy,
u)
\min (dis_ , dis_)
min(di
sx,u
,di
sy,u
),就是在 x
xx 和 y
yy 中找到較近的那乙個的距離。
w
uw_u
wu 就是點權,∑u∈
v\sum_
∑u∈v
是列舉所有節點。
即,所有節點的點權 ×
\times
× 離 u,v
u,vu,
v 較小的距離之和。
那麼,如果只要求乙個 u
uu,就是樹的重心,也就是本題的弱化版:
p1364 醫院設定
那麼,現在變成了雙重心(其實重心比中心形象一點),怎麼做?
考慮乙個 o(n
2)
o(n^2)
o(n2
) 的做法。
顯然,對於任意一組 x,y
x,yx,
y,會有乙個點集它們都離 x
xx 較近,另乙個點集離 y
yy 較近,這兩個點集的分界是一條邊。
那麼,我們只需要列舉斷邊(即將樹一分為二),形成點集,對兩邊的點集分別用重心模板求出,將答案之和取最小值。(n
)o(n)
o(n)
. (n
)o(n)
o(n)
總時間複雜度:o(n
2)
o(n^2)
o(n2).
期望得分:0
00 ~ 100pt
s100pts
100pts
.(出題人沒給部分分,洛谷評測機跑得快)
顯然,列舉斷邊無法優化,那我們考慮優化取重心。
下面我們要引出一些樹鏈剖分的知識。
乙個節點 i
ii,它所有兒子 u∈s
on
vu \in son_v
u∈sonv
中,siz
usiz _ u
sizu
(子樹權值和) 最大那個,我們稱之為重兒子,其餘是輕兒子。若干重兒子形成鏈是重鏈。
那麼,以 i
ii 為根的子樹的重心,如果不在 i
ii,那麼,重心是在重兒子的子樹中,還是輕兒子的子樹中?
常識告訴我們,肯定是在重兒子的子樹中比較好啊。(讀者可自證)
所以,我們只需要初始化每個節點的重兒子編號即可。
但是有個問題:萬一我斷邊,正好把重兒子的邊斷掉了呢?
所以,我們還要處理每個節點的次重兒子,重兒子沒了的時候用次重兒子。
然後,我們只需要列舉重鏈上的點作為重心的答案即可。
時間複雜度:o(n
×h
)o(n \times h)
o(n×h)
(h
hh 為樹高,因為重鏈長度 ≤
h\leq h
≤h,這也是就是題目明確說明 「樹高 ≤
100\leq 100
≤100
」 的用意所在啊)
實際得分:100pt
s100pts
100pts
.
#pragma gcc optimize(2)
#include
using
namespace std;
const
int n=
5e4+1;
inline
intread()
int x=0;
while
(isdigit
(ch)
) x=x*
10+ch-
'0',ch=
getchar()
;return x*f;
}int val[n]
,cdson[n]
,zdson[n]
;int ans=int_max,siz[n]
,f[n]
;int w[n]
,n,dep[n]
,cut;
vector<
int> g[n]
;inline
void
dfs(
int u,
int fa)
}inline
void
getans
(int u,
int now,
int all,
int&res)
//得到以當前節點為重心的答案
inline
void
solve
(int u)
}int
main()
for(
int i=
1;i<=n;i++
) w[i]
=read()
;dfs(1
,0);
solve(1
);printf
("%d\n"
,ans)
;return0;
}
P2726 SHOI2005 樹的雙中心 題解
csdn同步 原題鏈結 簡要題意 給定一棵樹,d 為 x 與 y 距離 d 0 選出兩個點 x,y 最小化 sum w u times min dis dis 這種水的樹形dp 黑題,沒幾個人做真是太可惜了 首先我們要明白這個式子是什麼意思。min dis dis 就是在 x 和 y 中找到較近的那...
SHOI2005 樹的雙中心
首先我們要知道,選擇兩個點 a,b 必定存在一條邊,割掉這條邊,兩個集合分別歸 a,b 管 再結合題目,我們就得到了乙個暴力的 n 2 做法 列舉個每條邊,分別對兩棵樹求帶權重心,更新答案 但這顯然是過不了這道題的,考慮對求帶權重心的過程進行優化 設 d x 為 x 所在集合內所有點到他的距離之和,...
BZOJ3302 Shoi2005 樹的雙中心
n 50000的樹,深度 100,有點權,選兩個點x,y,使 最小。dis取了min之後,整個樹就會以某條邊為分界線分成兩半,一半歸乙個點管。如果是兩棵完全獨立的樹的話,那肯定分別取這兩棵樹的帶權重心。但割掉某條邊再找兩邊重心,這種情況不一定是合法情況。例如 上圖中,虛線邊被斷開,兩邊的重心分別是星...