[codeforces1187E]Tree Painting

time limit per test : 2 seconds
memory limit per test : 256 megabytes

You are given a tree (an undirected connected acyclic graph) consisting of n n vertices. You are playing a game on this tree.

Initially all vertices are white. On the first turn of the game you choose one vertex and paint it black. Then on each turn you choose a white vertex adjacent (connected by an edge) to any black vertex and paint it black.

Each time when you choose a vertex (even during the first turn), you gain the number of points equal to the size of the connected component consisting only of white vertices that contains the chosen vertex. The game ends when all vertices are painted black.

Let’s see the following example:
在这里插入图片描述
Vertices 1 1 and 4 4 are painted black already. If you choose the vertex 2 2 , you will gain 4 4 points for the connected component consisting of vertices 2 2 , 3 3 , 5 5 and 6 6 . If you choose the vertex 9 9 , you will gain 3 3 points for the connected component consisting of vertices 7 7 , 8 8 and 9 9 .
Your task is to maximize the number of points you gain.

Input

The first line contains an integer n n — the number of vertices in the tree ( 2 n 2 1 0 5 ) (2≤n≤2⋅10^5) .

Each of the next n 1 n−1 lines describes an edge of the tree. Edge i i is denoted by two integers u i u_i and v i v_i , the indices of vertices it connects ( 1 u i , v i n , u i v i ) (1≤u_i,v_i≤n, ui≠vi) .It is guaranteed that the given edges form a tree.

Output

Print one integer — the maximum number of points you gain if you will play optimally.

Examples
Input

9
1 2
2 3
2 5
2 6
1 4
4 9
9 7
9 8

Output

36

Input

5
1 2
1 3
2 4
2 5

Output

14

Note

The first example tree is shown in the problem statement.

题目:
刚开始给定一个树,节点都是白色的,你需要做n次操作让他所有节点都变成黑色的。操作的定义如下:
第一次操作选取一个白色节点染成黑色
除了第一次操作外,每次操作选取一个白色的、与至少一个黑色节点相邻的节点,将其染成黑色,每次次操作的得分是当前操作被染色的节点所在的白色节点联通块的大小。

求出n次操作之后的最大可能总得分

题解:
我们发现,这个其实是一个给有根树定根的操作,根就是第一次染色的点,然后答案就是以这个点为根的树上所有子树的大小之和。
两次dfs计算即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll ans;
int n;
int sz[200004],du[200004];
struct edge{
    int to,nt;
}e[400004];
int ne,h[200004];
void add(int u,int v){
    e[++ne].to=v;e[ne].nt=h[u];h[u]=ne;
}
void dfs(int x,int fa){
    sz[x]=1;
    for(int i=h[x];i;i=e[i].nt){
        if(e[i].to==fa)continue;
        dfs(e[i].to,x);
        sz[x]+=sz[e[i].to];
    }
    ans+=sz[x];
}
void calc(int x,int fa,ll now){
    ans=max(ans,now);
    for(int i=h[x];i;i=e[i].nt){
        if(e[i].to==fa)continue;
        calc(e[i].to,x,now+n-2LL*sz[e[i].to]);
    }
}
int main(){
    memset(du,0,sizeof(du));
    memset(h,0,sizeof(h));
    ne=0;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        ++du[u];++du[v];
        add(u,v);add(v,u);
    }
    dfs(1,0);
    calc(1,0,ans);
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/94405445
今日推荐