您的位置:首页 > 其它

[BZOJ1131] [POI2008]Sta

2016-02-01 21:23 267 查看

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1131

题目大意

给定一棵树,找到一个根,使所有点的深度和最大

题解

树形DP

我们先把这棵树处理成以1为根的有根树

维护以每个点为根的子树的节点数size[]size[]

我们逐层O(1)O(1)查询

设a=fa[b],且已知ans[a]a=fa[b],且已知ans[a]

那么从a为根转为b为根,b的子树中的点深度都−1,其他点深度都+1那么从a为根转为b为根,b的子树中的点深度都-1,其他点深度都+1

所以得到递推式ans[i]=ans[fa[i]]−size[i]+n−size[i]ans[i]=ans[fa[i]]-size[i]+n-size[i]

{$m 10000000}
const
maxn=1000005;
var
w:array[0..3*maxn,1..2]of longint;
size,fa:array[0..maxn]of longint;
ans:array[0..maxn]of int64;
i,j,k:longint;
n,m,len,a,b,anss:longint;
procedure init(a,b:longint);
begin
w[len,1]:=b;
if w[a,2]=0
then w[a,2]:=len else w[w[a,1],2]:=len;
w[a,1]:=len; inc(len);
end;

procedure dfs1(a:longint);
var tt:longint;
begin
size[a]:=1; tt:=w[a,2];
while tt<>0 do
begin
if w[tt,1]<>fa[a]
then
begin
fa[w[tt,1]]:=a;
dfs1(w[tt,1]);
inc(size[a],size[w[tt,1]]);
ans[a]:=ans[w[tt,1]]+size[w[tt,1]];
end;
tt:=w[tt,2];
end;
end;

procedure dfs2(a:longint);
var tt:longint;
begin
tt:=w[a,2];
if a<>1
then ans[a]:=ans[fa[a]]+n-size[a]-size[a];
while tt<>0 do
begin
if w[tt,1]<>fa[a]
then dfs2(w[tt,1]);
tt:=w[tt,2];
end;
end;

begin
readln(n); len:=n+1;
for i:=1 to n-1 do
begin
readln(a,b);
init(a,b); init(b,a);
end;
dfs1(1);
dfs2(1);
anss:=0; ans[0]:=-1;
for i:=1 to n do
if ans[anss]<ans[i]
then anss:=i;
writeln(anss);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: