bzoj1131: [POI2008]Sta
思路:首先先求出以1为根的答案,然后考虑由i转移到i的儿子的答案的变化,显然以son[i]为根的子树的所有结点的深度都会减一,其余的点的深度都会加一,然后就可以直接O(n)求出所有结点的答案,然后取max更新答案即可。

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define maxn 1000005 int n,tot; int now[maxn],pre[2*maxn],son[2*maxn],dep[maxn],size[maxn]; long long dp[maxn]; int read(){ int x=0;char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()); for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; return x; } void add(int a,int b){ son[++tot]=b; pre[tot]=now[a]; now[a]=tot; } void link(int a,int b){ add(a,b),add(b,a); } void dfs(int x,int fa){ dep[x]=dep[fa]+1,dp[x]=dep[x],size[x]=1; for (int p=now[x];p;p=pre[p]) if (son[p]!=fa){ dfs(son[p],x); dp[x]+=dp[son[p]]; size[x]+=size[son[p]]; } } void tree_dp(int x,int fa){ for (int p=now[x];p;p=pre[p]) if (son[p]!=fa){ dp[son[p]]=dp[x]+n-2*size[son[p]]; tree_dp(son[p],x); } } int main(){ n=read(); for (int i=1,a,b;i<n;i++) a=read(),b=read(),link(a,b); dfs(1,0),tree_dp(1,0);int ans=0; for (int i=1;i<=n;i++) if (dp[ans]<dp[i]) ans=i; printf("%d\n",ans); return 0; }
标签:
树形dp
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术