P2726 SHOI2005 樹的雙中心 題解

2022-02-14 18:25:15 字數 2021 閱讀 9810

csdn同步

原題鏈結

簡要題意:

給定一棵樹,\(d_\) 為 \(x\) 與 \(y\) 距離(\(d_ = 0\)),選出兩個點 \(x,y\),最小化:

\[\sum_ (w_u \times \min(dis_ , dis_))

\]這種水的樹形dp 黑題,沒幾個人做真是太可惜了

首先我們要明白這個式子是什麼意思。

\(\min (dis_ , dis_)\),就是在 \(x\) 和 \(y\) 中找到較近的那乙個的距離。

\(w_u\) 就是點權,\(\sum_\) 是列舉所有節點。

即,所有節點的點權 \(\times\) 離 \(u,v\) 較小的距離之和。

那麼,如果只要求乙個 \(u\),就是樹的重心,也就是本題的弱化版:

p1364 醫院設定

那麼,現在變成了雙重心(其實重心比中心形象一點),怎麼做?

考慮乙個 \(o(n^2)\) 的做法。

顯然,對於任意一組 \(x,y\),會有乙個點集它們都離 \(x\) 較近,另乙個點集離 \(y\) 較近,這兩個點集的分界是一條邊。

那麼,我們只需要列舉斷邊(即將樹一分為二),形成點集,對兩邊的點集分別用重心模板求出,將答案之和取最小值。

總時間複雜度:\(o(n^2)\).

期望得分:\(0\) ~ \(100pts\).(出題人沒給部分分,洛谷評測機跑得快)

顯然,列舉斷邊無法優化,那我們考慮優化取重心。

下面我們要引出一些樹鏈剖分的知識。

乙個節點 \(i\),它所有兒子 \(u \in son_v\) 中,\(siz _ u\)(子樹權值和) 最大那個,我們稱之為重兒子,其餘是輕兒子若干重兒子形成鏈是重鏈。

那麼,以 \(i\) 為根的子樹的重心,如果不在 \(i\),那麼,重心是在重兒子的子樹中,還是輕兒子的子樹中?

常識告訴我們,肯定是在重兒子的子樹中比較好啊。(讀者可自證)

所以,我們只需要初始化每個節點的重兒子編號即可。

但是有個問題:萬一我斷邊,正好把重兒子的邊斷掉了呢?

所以,我們還要處理每個節點的次重兒子,重兒子沒了的時候用次重兒子。

然後,我們只需要列舉重鏈上的點作為重心的答案即可。

時間複雜度:\(o(n \times h)\)(\(h\) 為樹高,因為重鏈長度 \(\leq h\),這也是就是題目明確說明 「樹高 \(\leq 100\)」 的用意所在啊)

實際得分:\(100pts\).

#pragma gcc optimize(2)

#includeusing namespace std;

const int n=5e4+1;

inline int read()

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;

vectorg[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);

return 0;

}

P2726 SHOI2005 樹的雙中心 題解

同步 原題鏈結 簡要題意 給定一棵樹,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...

SHOI2005 樹的雙中心

首先我們要知道,選擇兩個點 a,b 必定存在一條邊,割掉這條邊,兩個集合分別歸 a,b 管 再結合題目,我們就得到了乙個暴力的 n 2 做法 列舉個每條邊,分別對兩棵樹求帶權重心,更新答案 但這顯然是過不了這道題的,考慮對求帶權重心的過程進行優化 設 d x 為 x 所在集合內所有點到他的距離之和,...

BZOJ3302 Shoi2005 樹的雙中心

n 50000的樹,深度 100,有點權,選兩個點x,y,使 最小。dis取了min之後,整個樹就會以某條邊為分界線分成兩半,一半歸乙個點管。如果是兩棵完全獨立的樹的話,那肯定分別取這兩棵樹的帶權重心。但割掉某條邊再找兩邊重心,這種情況不一定是合法情況。例如 上圖中,虛線邊被斷開,兩邊的重心分別是星...