titre
Signification des questions:
Compte tenu d'un arbre, le point de départ est un blanc, un tachée chaque fois que vous pouvez pointer fraction est obtenue qui ne contient que le nombre de points de blocs de communication de point blanc dans le point de rattachement actuel. Sortie jusqu'à score.
analyse:
Chaque fois qu'un des opérations ponctuelles sera divisé en sous - arbres arbre m, et nous nœud parent certainement la première exploitation, puis manipuler les nœuds enfants, pensez donc naturellement d'un dp d'arbre. Mais nous ne savons pas la racine, il sera effectué pour changer la racine.
Arbre dp, dp [i] i est exprimée dans le sous - arbre enraciné à la valeur maximale obtenue dans l'opération, dp [i] = dp [ t] + fils [i] (t i du nœud enfant, fils [i] est Le secteur de la section de petits - i). Transfert au changement de racine dp [t] = dp [i ] - fils [t] + fils [i] - fils [t], le score actuel du noeud parent de ce noeud est maintenant à soustraire les petits - enfants de racine d' origine noeuds, ainsi que maintenant la contribution originale du noeud parent de t. Notez que cette fois la racine a changé, nous devons changer la valeur du fils [t], puis revenir quand faire marche arrière.
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
int son[200005];
ll dp[200005];
vector<int> g[200005];
void dfs1(int x,int fa)
{
if( g[x].size() == 1 && g[x][0] == fa )
{
son[x] = 1;
dp[x] = 1;
return;
}
for (int i = 0; i < g[x].size(); i++)
{
int t = g[x][i];
if( t == fa ) continue;
dfs1(t,x);
son[x] += son[t];
dp[x] += dp[t];
}
son[x] ++;
dp[x] += son[x];
}
void dfs2(int x,int fa)
{
for (int i = 0; i < g[x].size(); i++)
{
int t = g[x][i];
if( t == fa ) continue;
int gap = son[x] - son[t];
dp[t] = dp[x] - son[t] + gap;
son[t] += gap;
dfs2(t,x);
son[t] -= gap;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for (int i = 1; i < n; i++)
{
int x,y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(1,0);
dfs2(1,0);
ll ans = 0;
for (int i = 1; i <= n; i++)
{
//cout << i << ' ' << dp2[i] << '\n';
ans = max(ans,dp[i]);
}
cout << ans << '\n';
return 0;
}