模板 樹的重心

2021-08-20 19:50:48 字數 1164 閱讀 1413

定義:找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心,刪去重心後,生成的多棵樹盡可能平衡。

首先,利用前向星存邊建立邊表。由於無向,所以要連兩次邊。我們用一次 df

s() dfs

()

建立以1為根節點時每個結點所在子樹的結點數。

接下來考慮把這個點刪掉的結果,如果乙個非根結點有

p p

個兒子,那麼刪掉這個點之後會有 p+

1' role="presentation" style="position: relative;">p+1

p+1個連通分量,因為這個結點不是根節點,那麼除了這個結點及它的所有子樹外還有乙個連通分量,我們將之稱為這個結點的上方子樹。接下來,計算這些子樹(包括上方子樹)的 si

zes iz

e再從中找個最大值,因為總共有

n n

個結點所以有

n' role="presentation" style="position: relative;">n

n個最大值,接下來在其中挑乙個最小的即可,當這個值取到最小時的那個結點就是這棵樹的重心。si

zes iz

e的計算方法:

上述的計算過程都在 df

s dfs

中執行完成,故時間複雜度和空間複雜度均為 o(

n)o (n

)

struct tree ;

int n, root, maxsize;

std::vector

< edgetype > edge;

std::vector

< int > head, size;

tree() : edge(0), head(0), size(0) {}

tree(int n) : n(n), head(n + 1, -1), size(n + 1) {}

inline

void addedge(int from, int to) );

head[from] = edge.size() - 1;

}void center(int u, int p)

ret = std::max(ret, n - size[u]);

if (ret < maxsize)

}};

模板 樹的重心

模板 求樹的重心 任務 求樹的重心 介面 vector way maxn 無向圖 int siz 該節點的子節點個數 包括自己 int mu 該節點的 最大,節點數最多 子樹的節點數 allnode 根節點的子節點個數 siz root int getroot int u,int fa 返回以u為根...

樹的重心 模板

刪除重心後,子樹的最大權值最小 dfs遍歷每個點,node的所有子樹除了它的兒子們還有它往父親那個方向的一顆子樹 權值 總權值 所有子樹權值和 1 下面的 權值為邊權 include using namespace std const int maxn 1e5 100,inf 0x3f3f3f3f ...

樹的重心 poj3701 模板題

樹的重心也叫樹的質心。找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心,刪去重心後,生成的多棵樹盡可能平衡。思路 dfs深搜 回溯 poj3701 有多個重心 ac include include include include include include includ...