Stop the Hollyweb! No DRM in HTML5.

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.

 

posted on 2013-03-06 19:37  灰天飞雁  阅读(888)  评论(0编辑  收藏  举报

填写您的邮件地址,订阅我们的精彩内容:  点击这里给我发消息

添加到收藏夹