POJ2631 树最长路径
大意:给出树的两节点之间的边长,求最长路径。
很水的一个两次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.