【题解】Luogu p3478 [POI2008]STA-Station 动态规划
题目描述#
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
输入输出格式#
输入格式#
第一行一个数n,表示树上共有n个点
接下来n−1行,表示n−1条边;每行两个数,表示这条边的两个端点
输出格式#
一个数,表示以该节点为根时,所有点的深度之和最大
思路#
- 设u为v的父节点
- 用f[u]表示以u为根节点时的最大深度和,用size[u]表示u的子树大小
- 以u为根的树,变成以儿子v为根的树,
- 那么所有在v的子树上的节点的深度都会减1,深度和就会减少size[v],
- 所有不在v的子树上的节点的深度都会+1,深度和就会加上n−size[v];
得到公式
f[v]=f[u]+n−2∗size[v]
- 所以,只需求出以1为根节点时的深度和;剩下的答案都可以递推出来
代码#
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 66 67 68 69 70 71 72 73 | #include<cmath> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #define re register int using namespace std; int const maxn=1e6+50; inline int read(){ int x=0,w=1; char ch= getchar (); while (ch!= '-' &&(ch< '0' ||ch> '9' )) ch= getchar (); if (ch== '-' ) w=-1,ch= getchar (); while (ch>= '0' &&ch<= '9' ) x=(x<<1)+(x<<3)+ch-48,ch= getchar (); return x*w; } long long sum[maxn],size[maxn],ans[maxn]; int tot=1,dep[maxn],n,h[maxn]; struct data { int v,next; }e[maxn<<1]; inline void add( int u, int v) { e[tot].v=v; e[tot].next=h[u]; h[u]=tot++; } void dfs( int u, int f){ sum[u]=dep[u]=dep[f]+1;size[u]=1; for (re i=h[u];i;i=e[i].next) { int v=e[i].v; if (v==f) continue ; dfs(v,u); size[u]+=size[v]; sum[u]+=sum[v]; } } void DFS( int u, int f) { for (re i=h[u];i;i=e[i].next) { int v=e[i].v; if (v==f) continue ; ans[v]=ans[u]+n-2*size[v]; DFS(v,u); } } int main() { n=read(); for (re i=1,a,b;i<n;++i) { a=read(),b=read(); add(a,b);add(b,a); } dfs(1,0); ans[1]=sum[1]; DFS(1,0); int pos=0; for (re i=1;i<=n;++i) { if (ans[pos]<ans[i]) pos=i; } printf ( "%d\n" ,pos); return 0; } /* 8 1 4 5 6 4 5 6 7 6 8 2 4 3 4 */ |
作者: bbqub
出处:https://www.cnblogs.com/bbqub/p/8919789.html
版权:本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步