題面
題意:
一棵樹,有個節點,現在要找一個點作爲根節點使得這棵樹的所有子樹的大小和最大。求出最大值。
思路:
先利用一次dfs求出以1爲根的答案,順便統計一下以爲根節點的子樹的大小和以爲根節點的子樹的所有子樹的大小和。
再進行一次dfs進行換根操作更新最大值,設爲以爲根時的答案,那麼想要得到以它的孩子爲根的答案,首先需要斷掉之間的邊,那麼斷掉後剩下的大小爲。然那麼就等於。
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;
}