题意:给你一棵树,起初,每个节点都是白色的,现在要把树染黑,每次选择一个节点,可以获得与该点连通的白色节点的总数的得分,然后再将该节点染黑。
选择节点的要求,第一次可以以任意选择,后面就只能选择与黑色节点相连的白色节点
代码:
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<"="<<x<<endl;
#define debug2(x, y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl;
#define debug3(x, y, z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl;
const int maxn = 2e5+50;
using namespace std;
typedef long long ll;
vector <int> maps[maxn];
int n;
ll sz[maxn], dp[maxn];
void dfs1(int u, int fa){
sz[u] = 0;
for(int i=0, len=maps[u].size(); i<len; i++){
int v = maps[u][i];
if(v != fa){
dfs1(v, u);
sz[u] += sz[v];
dp[u] += dp[v];
}
}
sz[u]++;
dp[u] += sz[u];
}
ll ans;
void dfs2(int u, int fa){
for(int i=0, len=maps[u].size(); i<len; i++){
int v = maps[u][i];
if(v != fa){
dp[v] = dp[u] + n - 2*sz[v]; //简单推一推,就能推出来
ans = max(ans, dp[v]);
dfs2(v, u);
}
}
}
int main()
{
scanf("%d", &n);
for(int i=1, a, b; i<n; i++){
scanf("%d%d", &a, &b);
maps[a].push_back(b);
maps[b].push_back(a);
}
dfs1(1, 1);
ans = dp[1];
dfs2(1, 1);
printf("%lld
", ans);
return 0;
}