SHOI2005 樹的雙中心

2022-05-11 16:02:51 字數 986 閱讀 4106

首先我們要知道,選擇兩個點\(a,b\),必定存在一條邊,割掉這條邊,兩個集合分別歸\(a,b\)管

再結合題目,我們就得到了乙個暴力的\(n^2\)做法:列舉個每條邊,分別對兩棵樹求帶權重心,更新答案

但這顯然是過不了這道題的,考慮對求帶權重心的過程進行優化:

設\(d(x)\)為\(x\)所在集合內所有點到他的距離之和,\(sz(x)\)表示以\(x\)為根的子樹的大小,我們可以得到:

\[d(v)=d(u)+sz(rt)-sz(v)-sz(v)

\]其中\(u=fa(v)\),則若乙個點\(v\)比\(u\)更優,即\(d(v),可以得到\(2\times sz(v)>sz(rt)\)

顯而易見的是,對於每乙個\(u\),符合條件的\(v\)最多只有乙個,則演算法得到了很大的優化

我們對每乙個點預處理出乙個重兒子和次重兒子,處理出次重兒子的原因是割邊後\(sz\)會發生變化

然後在更新過程中只要考慮當前重兒子是否滿足條件即可,最壞時間複雜度\(o(n \times dep)\)

#includeusing namespace std;

const int n=5e4+1;

int n,ans,cnt,no,head[n],f[n],a[n];

int fa[n],sz[n],son[n],nson[n],dep[n];

struct edgeedge[n<<1];

void ins(int x,int y)

void dfs(int x,int fat)

void cut()

}int read()

while(isdigit(ch))

return x*f;

}int main()

for(int i=1;i<=n;i++) a[i]=read();

dfs(1,0);cut();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...

P2726 SHOI2005 樹的雙中心 題解

csdn同步 原題鏈結 簡要題意 給定一棵樹,d 為 x 與 y 距離 d 0 選出兩個點 x,y 最小化 sum w u times min dis dis 這種水的樹形dp 黑題,沒幾個人做真是太可惜了 首先我們要明白這個式子是什麼意思。min dis dis 就是在 x 和 y 中找到較近的那...

BZOJ3302 Shoi2005 樹的雙中心

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