给定一个 n 个点的树,请求出一个结点,使得以这个结点为根时,所有结点的深度之和最大,输出最大的深度之和即可。
**注意:**根的深度为 1
分析
二次扫描与换根法
模板题
给一个无根图,先以1顶点跑一边 dfs 记录 sz[],sum[].d[] 信息
再跑一边 $ dfs $ ,用父亲结点的信息去进一步更新儿子结点
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| int n; struct node{ int to,ne; }e[1000005<<1]; int h[1000005],cnt = 1; void add(int u,int v){ e[++cnt] = {v,h[u]}; h[u] = cnt; } int sz[1000005];
int d[1000005]; int sum[1000005];
vector<int> res; void dfs(int u,int fa){ d[u] = d[fa] + 1; sz[u] = 1; sum[u] = d[u]; for(int i = h[u];i;i = e[i].ne){ int v = e[i].to; if(v == fa) continue; dfs(v,u); sum[u] += sum[v]; sz[u] += sz[v]; } } void dfs1(int u,int fa){ res.push_back(sum[u]); for(int i = h[u];i;i = e[i].ne){ int v = e[i].to; if(v == fa) continue; sum[v] = sum[u] - sz[v] + n - sz[v]; dfs1(v,u); } } signed main() { _orz; cin >> n; for(int i = 1;i <= n-1;i++){ int u,v;cin>>u>>v; add(u,v);add(v,u); } dfs(1,0); dfs1(1,0);
int p = 0; int res = 0; for(int i = 1;i <= n;i++){ if(res < sum[i]){ res = sum[i]; p = i; } } cout << res << endl; return 0; }
|