题解 CF1187E 【Tree Painting】
树形DP好题!
正题
我们可以发现,确定第一个点后,后面选点的顺序就不影响权值了。
所以,我们设
我们发现,
易得递推式:
于是我们得出:
然而,怎么算其它的
所以我们要使用换根DP。
怎么换根呢?
来看下面的图:
易得:
Code:
#include <cstdio>
#include <vector>
using namespace std ;
typedef long long ll ;
const int MAXN = 2e5 + 10 ;
int n , size[MAXN] ;
vector <int> G[MAXN] ;
ll f[MAXN] , g[MAXN] , ans ;
ll max (ll a , ll b) {
return a > b ? a : b ;
}
void dfs1 (int x , int fa) {
size[x] = 1 ;
for (int i = 0 ; i < G[x].size () ; i++) {
int v = G[x][i] ;
if (v == fa) continue ;
dfs1 (v , x) ;
size[x] += size[v] ;
f[x] += f[v] ;
}
f[x] += size[x] ;
}
void dfs2 (int x , int fa) {
if (x != 1) {
g[x] = g[fa] + n - size[x] * 2 ;
ans = max (ans , g[x]) ;
}
for (int i = 0 ; i < G[x].size () ; i++) {
int v = G[x][i] ;
if (v == fa) continue ;
dfs2 (v , x) ;
}
}
int main () {
scanf ("%d" , &n) ;
for (int i = 1 ; i < n ; i++) {
int u , v ;
scanf ("%d %d" , &u , &v) ;
G[u].push_back (v) ;
G[v].push_back (u) ;
}
dfs1 (1 , 0) ;
ans = g[1] = f[1] ;
dfs2 (1 , 0) ;
printf ("%lld" , ans) ;
return 0 ;
}