樹的重心專題

2022-06-27 13:24:12 字數 3395 閱讀 7381

解題思路:選擇乙個節點作為根,設dp[i]表示以i為根的樹的總節點個數,dp[i]=滿足j為其子節點的的d[j]之和再加1(根節點)。只需在dfs過程中找到最大的子樹節點,並與其上方的節點數做比較,就可以找出樹的重心了。

題目大意:對於一棵無根樹,找到乙個點使得樹以該點為根的有根樹,最大子樹(選擇該節點後其子樹的最大節點)的節點數最小。

模板:

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn = 5e4 + 5

;int head[maxn], to[maxn << 1], nx[maxn << 1

], tot;

bool

vst[maxn];

int min = 0x3f3f3f3f

, key;

intcnt[maxn], n;

vector

vec;

void add_edge(int u, int

v)

int dfs(int u, int

par)

}if(max < n -cnt[u])

max = n -cnt[u];

if(max

else

if(max ==min)

return

cnt[u];}

intmain()

dfs(

1, 1

); sort(vec.begin(), vec.end());

for(int i = 0; i < vec.size(); i++)

printf(

"%d%c

", vec[i], i + 1 == vec.size() ? '

\n' : '');

return0;

}

view code

#include#include

#include

#include

#include

using

namespace

std;

#define inf 1<<30

int n,dp[101

],node,minans;

vector

edge[101];

int dfs(int m,int

fa) }

maxnode=max(maxnode,n-dp[m]); //

再與上方的節點數做比較

if(maxnode

return

dp[m];}

intmain()

for(int i=1;i<=n;i++) //

初始化都是1,即根節點本身

minans=inf;

dfs(

1,-1

); cout"}

return0;

}

樹的帶權重心:----解釋版:

#include//

樹的重心版本

using

namespace

std;

const

int maxn=4e5+20

;struct

nodenode[maxn];

intlen;

inthead[maxn];

void add(int a,int

b)int

m;bool

vis[maxn];

intc_tre[maxn];

intnum[maxn];

bool visit[maxn];//

對應權重點

intk;

long

long all=0

;int

bkbk;

void

init()

void dfs1(int x,int

pre)

for(int i=head[x];i!=-1;i=node[i].next)

return ;//

返回的這個num 帶自身。

}void dfs(int u,int fa)//

求樹的帶權重心模板。

if(mx<=k)

for(int i=head[u]; i!=-1; i=node[i].next)

}void dfs3(int c,int len)

}int

main()

//k*=2;

for(int i=0;i1;i++)

dfs1(

1,-1);//

記錄一下權重.

dfs(1,-1);//

計算一下帶權重心。

all=0

; memset(vis,

false,sizeof

(vis));

dfs3(bkbk,

0);//

計算一下各個點距離 重心的權重和。

cout

return0;

}

#include#include

#include

#include

#include

#define maxn 200005

using

namespace

std;

//找樹的重心

int n,popu[maxn],tot=0

;vector

g[maxn];

void

init()

for(int i=1;i<=n;i++)

}bool

vis[maxn];

intfa[maxn],sum[maxn],dist[maxn],maxsum[maxn];

long

long

cost[maxn];

void dfs(int

i) maxsum[i]=max(maxsum[i],tot-sum[i]);

}void

solve()

}for(int i=1;i<=n;i++)

}printf("\n

");memset(vis,

0,sizeof

(vis));

dfs(x);

cout

}int

main()

專題 樹的重心

定義1 找到乙個點,刪除它得到的森林中最大的子樹節點數最少,那麼這個點就是這棵樹的重心。定義2 刪除重心後得到的所有子樹,其頂點樹必然不超過n 2 性質1 樹中所有點到某個點的距離和中,到重心的距離和是最小的 如果有兩個重心,那麼他們的距離和一樣。性質2 把兩個樹通過一條邊相連得到乙個新的樹,那麼新...

求樹的重心

題目 題意 給定一棵樹,求樹的重心的編號以及重心刪除後得到的最大子樹的節點個數size,如果size相同就選取編號最小的.分析 首先要知道什麼是樹的重心,樹的重心定義為 找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵 樹的重心,刪去重 心後,生成的多棵樹盡可能平衡.實際上樹的重心...

模板 樹的重心

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