您的位置:首页 > 其它

POJ2631 树最长路径

2013-03-06 19:37 148 查看
大意:给出树的两节点之间的边长,求最长路径。

很水的一个两次dp+dfs写法。内存占用很大,估计近期要重写(内存优化+两次bfs做法)。

program basic;

Const
maxn=10000;
maxm=200;

Var
t,fa,wf,f1,f2,f3,d1,d2:array[0..maxn] of longint;
a,aw,ch,w:array[0..maxn,0..maxm] of longint;
v:array[0..maxn] of boolean;
h,st,ed,gw,i,j,n,m,ans:longint;
c:char;

Procedure fopen;
begin
assign(input,'basic.in');
assign(output,'basic.out');
reset(input);
rewrite(output);
end;

Procedure fclose;
begin
close(input);
close(output);
end;

Procedure Add(st,ed,gw:longint);
begin
inc(t[st]);
a[st,t[st]]:=ed;
aw[st,t[st]]:=gw;
end;

Function max(a,b:longint):longint;inline;
begin
if a>b then exit(a) else exit(b);
end;

Procedure dfs(P:longint);
var
i,x:longint;
begin
v[p]:=true;
for i:=1 to t[p] do
begin
x:=a[p,i];
if not v[x] then
begin
dfs(x);
inc(ch[p,0]);
ch[p,ch[p,0]]:=x;
w[p,ch[p,0]]:=aw[p,i];
fa[x]:=p;
wf[x]:=w[p,ch[p,0]];
end;
end;
end;

Procedure build;
begin
h:=random(n)+1;
fillchar(v,sizeof(v),false);
dfs(h);
end;

procedure dfs1(P:longint);
var
i,x:longint;
begin
for i:=1 to ch[p,0] do
begin
x:=ch[p,i];
dfs1(x);
if f1[x]+w[p,i]>f1[p] then
begin
d1[p]:=x;
f1[p]:=f1[x]+w[p,i];
end;
end;

for i:=1 to ch[p,0] do
begin
x:=ch[p,i];
if x=d1[p] then continue;
if f1[x]+w[p,i]>f2[p] then
begin
d2[p]:=x;
f2[p]:=f1[x]+w[p,i];
end;
end;
end;

Procedure dfs2(P:longint);
var
i:longint;
begin
if p<>h then
if d1[fa[p]]<>p then f3[p]:=max(f1[fa[p]],f3[fa[p]])+wf[p] else f3[p]:=max(f2[fa[p]],f3[fa[p]])+wf[p];
for i:=1 to ch[p,0] do
dfs2(ch[p,i]);
end;

begin
n:=0;
while not eof do
begin
readln(st,ed,gw);
n:=max(n,st);
n:=max(n,ed);
Add(st,ed,gw);
Add(ed,st,gw);
end;
build;
dfs1(h);
dfs2(h);
ans:=0;
{writeln(h);
for i:=1 to n do
begin
writeln('node#',i,' chnum=',ch[i,0],' fa=',fa[i],' wf[i]=',wf[i]);
writeln(f1[i],' ',f2[i],' ',f3[i]);
for j:=1 to ch[i,0] do
write(ch[i,j],' ',w[i,j],' || ');
writeln;
end;}
for i:=1 to n do
ans:=max(ans,max(f1[i],max(f2[i],f3[i])));
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: