TYVJ 1520 [树的直径]
求树的最长链,用了SPFA+SLF(表示BFS就可以,作者纯属DT)
[pascal 代码]
Const maxn=100000; maxq=1000000; VAR a,b,e,dis,f:array[1..maxn]of longint; q:array[1..maxq]of longint; vis:array[1..maxn]of boolean; n,m,head,tail,maxdis,maxi,i:longint; Procedure addgraph(x,y,z:longint); begin inc(m); a[m]:=x;b[m]:=y;e[m]:=z; end; Procedure init; var i,x,y,z:longint; begin readln(n); for i:=1 to n-1 do begin readln(x,y,z); addgraph(x,y,z); addgraph(y,x,z); end; end; Procedure qsort(l,r:longint); var i,j,x,y:longint; begin i:=l;j:=r;x:=a[(l+r)shr 1]; Repeat while a[i]<x do inc(i); while a[j]>x do dec(j); if i<=j then begin y:=a[i];a[i]:=a[j];a[j]:=y; y:=b[i];b[i]:=b[j];b[j]:=y; y:=e[i];e[i]:=e[j];e[j]:=y; inc(i);dec(j); end; Until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j); end; Procedure ready; var i:longint; begin fillchar(f,sizeof(f),0); qsort(1,m); for i:=1 to m do if f[a[i]]=0 then f[a[i]]:=i; f[n+1]:=m+1; for i:=n downto 1 do if f[i]=0 then f[i]:=f[i+1]; end; Function outque:longint; begin inc(head); if head>maxq then head:=1; exit(q[head]); end; Procedure enque(x:longint); //SLF begin vis[x]:=true; if dis[x]>dis[q[head]] then begin inc(tail); if tail>maxq then tail:=1; q[tail]:=x; end else begin dec(head); if head<1 then head:=maxq; q[head]:=x; end; end; Procedure spfa(s:longint); //SPFA+SLF var i,pre:longint; begin fillchar(vis,sizeof(vis),false); fillchar(dis,sizeof(dis),$3f); head:=0;tail:=1;q[1]:=s;dis[s]:=0; while head<>tail do begin pre:=outque; for i:=f[pre] to f[pre+1]-1 do begin if dis[pre]+e[i]<dis[b[i]] then begin dis[b[i]]:=dis[pre]+e[i]; if not vis[b[i]] then enque(b[i]); end; end; vis[pre]:=false; end; end; Begin init; ready; spfa(1); maxdis:=0; for i:=1 to n do if dis[i]>maxdis then begin maxdis:=dis[i]; maxi:=i; end; spfa(maxi); maxdis:=0; for i:=1 to n do if dis[i]>maxdis then maxdis:=dis[i]; writeln(maxdis); End.