题面
题意:
一棵树,有 n n n个节点,现在要找一个点作为根节点使得这棵树的所有子树的大小和最大。求出最大值。
思路:
先利用一次dfs求出以1为根的答案,顺便统计一下以
i
i
i为根节点的子树的大小
s
i
z
i
siz_i
sizi和以
i
i
i为根节点的子树的所有子树的大小和
d
p
i
dp_i
dpi。
再进行一次dfs进行换根操作更新最大值,设
d
p
u
dp_u
dpu为以
u
u
u为根时的答案,那么想要得到以它的孩子
v
v
v为根的答案
d
p
v
dp_v
dpv,首先需要断掉
u
,
v
u,v
u,v之间的边,那么断掉
v
v
v后剩下的大小为
r
e
s
=
d
p
u
−
s
i
z
v
−
d
p
v
res=dp_u-siz_v-dp_v
res=dpu−sizv−dpv。然那么
d
p
v
dp_v
dpv就等于
d
p
v
+
t
m
p
−
s
i
z
v
+
n
dp_v+tmp-siz_v+n
dpv+tmp−sizv+n。
code
#include<bits/stdc++.h>
using namespace std;
const long long N = 1e6+100;
vector<long long> G[N];
long long dp[N];long long siz[N];
void dfs1(long long u,long long fa){
siz[u]=1;
for(auto v:G[u]){
if(v==fa) continue;
dfs1(v,u);
siz[u]+=siz[v];
dp[u]+=dp[v];
}
dp[u]+=siz[u];
}
long long ans=0;
long long n,u,v;
void dfs2(long long u,long long fa){
ans=max(ans,dp[u]);
for(auto v:G[u]){
if(v==fa) continue;
long long res=dp[u]-dp[v]-siz[v];
dp[v]=(dp[v]+res+n-siz[v]);
dfs2(v,u);
}
}
int main(){
cin>>n;
for(long long i=1;i<=n-1;i++){
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(1,0);
dfs2(1,0);
cout<<ans<<endl;
return 0;
}