解題思路:選擇乙個節點作為根,設dp[i]表示以i為根的樹的總節點個數,dp[i]=滿足j為其子節點的的d[j]之和再加1(根節點)。只需在dfs過程中找到最大的子樹節點,並與其上方的節點數做比較,就可以找出樹的重心了。
題目大意:對於一棵無根樹,找到乙個點使得樹以該點為根的有根樹,最大子樹(選擇該節點後其子樹的最大節點)的節點數最小。
模板:
#include#includeview code#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;
}
#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為根...