给定一棵 \(n\) 个点的树,初始全是白点,要求你做 \(n\) 步操作,每一次选定一个与一个黑点相隔一条边的白点,将它染成黑点,然后获得该白点被染色前所在的白色联通块大小的权值。第一次操作可以任意选点。求可获得的最大权值。
Solution
显然如果选定了开始点,那么答案就是固定的
设开始点为根,则答案为所有子树的大小和
设以 \(i\) 为根的答案为 \(f[i]\)
则显然有 \(f[v]-f[u] = n-2s[v]\)
两次 DFS 即可
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 1000005; int n,f[N],s[N],t1,t2,vis[N]; vector <int> g[N]; void dfs1(int p) { vis[p]=1; s[p]=1; for(int q:g[p]) if(vis[q]==0) { dfs1(q); s[p]+=s[q]; } } void dfs2(int p) { vis[p]=1; for(int q:g[p]) if(vis[q]==0) { f[q]=f[p]+n-2*s[q]; dfs2(q); } } signed main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<n;i++) { cin>>t1>>t2; g[t1].push_back(t2); g[t2].push_back(t1); } dfs1(1); memset(vis,0,sizeof vis); for(int i=1;i<=n;i++) f[1]+=s[i]; dfs2(1); cout<<*max_element(f+1,f+n+1); }
来源:https://www.cnblogs.com/mollnn/p/12630710.html