BZOJ1131 [POI2008]Sta 其他
原文链接http://www.cnblogs.com/zhouzhendong/p/8081100.html
题目传送门 - BZOJ1131
题意概括
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大。
题解
嘻,这题不卡栈。
假设以1为根
先跑一遍dfs,算出每一个子树的节点数size,同时算出以1为根节点的深度和。
然后再跑一遍dfs,这一回,我们就可以算答案了。
假设我们要把树根从一条边的一个节点移向另一个节点,那么,这两个节点为根的答案差就是这条边两端的节点个数差。因为其中一个节点代表的子树上的节点都要多走一步到根,而另一边少走一步。这样就可以在O(n)的时间复杂度内solve这一题了。
代码
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 | #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> using namespace std; typedef long long LL; const int N=1000005; struct Gragh{ int cnt,y[N*2],nxt[N*2],fst[N]; void clear(){ cnt=0; memset (fst,0, sizeof fst); } void add( int a, int b){ y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt; } }g; int n,size[N],ans; LL sum[N],res[N]; void dfs1( int rt, int pre){ size[rt]=1,sum[rt]=0; for ( int i=g.fst[rt];i;i=g.nxt[i]) if (g.y[i]!=pre){ int s=g.y[i]; dfs1(s,rt); size[rt]+=size[s]; sum[rt]+=sum[s]; } sum[rt]+=size[rt]-1; } void dfs2( int rt, int pre){ res[rt]=res[pre]-size[rt]+(n-size[rt]); if (!ans||res[rt]>res[ans]||(res[rt]==res[ans]&&rt<ans)) ans=rt; for ( int i=g.fst[rt];i;i=g.nxt[i]) if (g.y[i]!=pre) dfs2(g.y[i],rt); } int main(){ g.clear(); scanf ( "%d" ,&n); for ( int i=1,a,b;i<n;i++){ scanf ( "%d%d" ,&a,&b); g.add(a,b); g.add(b,a); } dfs1(1,0); ans=0; res[0]=sum[1]+n; dfs2(1,0); printf ( "%d" ,ans); return 0; } |
【推荐】国内首个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应用必不可少的技术