Title:
Give you a tree. At the beginning, every point is white. Now you need to blacken one by one. At the beginning, you can choose any point, but later you need to choose a point beside the black point. The value you get each time you blacken is the size of the white block (including itself) adjacent to the point you choose, and ask what the maximum value you finally get.
Explanation:
After a little modeling, it can be found that it is the best to paint color from a certain leaf node inside, because if you start in the middle, you will say that it is divided into multiple blocks, and it will not be the best. Then we use dp[i][1] to show how much we get when we go down to the ith point, and dp[i][1] to show how much we get when we go back to the ith point.
Then dp[i][1] is equal to the number of its sons + dp [sons] [1], dp[i][0] wants to enumerate the optimal situation of son node selection.
dp[ne][0]+dp[x][1]-son[x]-dp[ne][1]+son[1]-son[ne]
That is, the maximum value of the son's return plus the value of dfs from its beginning - the current son's value - the number of sons added to dp[x][1] at the beginning + the number of points from its beginning except the current son's number.
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=2e5+5; ll son[N],dp[N][2]; struct node { int to,next; }e[N*2]; int cnt,head[N]; void add(int x,int y) { e[cnt].to=y; e[cnt].next=head[x]; head[x]=cnt++; } void fson(int x,int fa) { son[x]=1; for(int i=head[x];~i;i=e[i].next) { int ne=e[i].to; if(ne==fa) continue; fson(ne,x); son[x]+=son[ne]; } } void dfs(int x,int fa) { dp[x][1]=son[x]; dp[x][0]=son[1]-son[x]+1; for(int i=head[x];~i;i=e[i].next) { int ne=e[i].to; if(ne==fa) continue; dfs(ne,x); dp[x][1]+=dp[ne][1]; } for(int i=head[x];~i;i=e[i].next) { int ne=e[i].to; if(ne==fa) continue; dp[x][0]=max(dp[x][0],dp[ne][0]+dp[x][1]-son[x]-dp[ne][1]+son[1]-son[ne]); } } int main() { int n,x,y; memset(head,-1,sizeof(head)); scanf("%d",&n); for(int i=1;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x); fson(1,0); dfs(1,0); printf("%lld\n",max(dp[1][0],dp[1][1])); return 0; }