I and OI
Past...

简单的LCA.

有一个结论,每个party中最远的点对中,必有一个点是该party中深度最大的点.

然后记low[i]为第i个party的最深点,对每一个点查询dist(i,low[belong[i]]).

belong就是第i个点属于哪个party.

对于树上两点,dist(u,v)=depth(u)+depth(v)-2*depth(lca(u,v)).

一开时用RMQ的LCA死活过不去.无奈,只好去学了tarjan的LCA.

code:

/************************************************************** 
    Problem: 1776
    User: exponent 
    Language: Pascal 
    Result: Accepted 
    Time:1940 ms 
    Memory:15628 kb 
****************************************************************/ 
  
{$M 10000000}
type  edge=record
      v,n:longint; 
end; 
const maxn=200001; 
      maxk=100000; 
var   e:array[0..maxn] of edge; 
      g:array[0..maxn*2] of edge; 
      h,hx,q,d,b,f,dep,anc:array[0..maxn] of longint; 
      vis:array[0..maxn] of boolean; 
      low,ans:array[0..maxk] of longint; 
      n,i,k,fi,cx,cnt,root:longint; 
  
  
      procedure add(u,v:longint); 
      begin
            inc(cnt); 
            e[cnt].v:=v; 
            e[cnt].n:=h[u]; 
            h[u]:=cnt; 
      end; 
  
      procedure addx(u,v:longint); 
      begin
            inc(cx); 
            g[cx].v:=v; 
            g[cx].n:=hx[u]; 
            hx[u]:=cx; 
      end; 
  
      procedure bfs(u:longint); 
      var   v,p,head,tail:longint; 
      begin
            head:=0; tail:=1; 
            q[1]:=u; 
            d[1]:=1; 
            while head<tail do
            begin
                  inc(head); 
                  u:=q[head]; 
                  low[b[u]]:=u; 
                  dep[u]:=d[head]; 
                  p:=h[u]; 
                  while p<>0 do
                  begin
                        v:=e[p].v; 
                        inc(tail); 
                        q[tail]:=v; 
                        d[tail]:=d[head]+1; 
                        p:=e[p].n; 
                  end; 
            end; 
      end; 
  
      function getf(x:longint):longint; 
      begin
            if f[x]<>x then f[x]:=getf(f[x]); 
            exit(f[x]); 
      end; 
  
      procedure union(u,v:longint); 
      var   fu,fv:longint; 
      begin
            fu:=getf(u); 
            fv:=getf(v); 
            if fu<>fv then f[fu]:=fv; 
      end; 
  
      function max(a,b:longint):longint; 
      begin
            if a>b then exit(a); exit(b); 
      end; 
  
      procedure LCA(u:longint); 
      var   v,p,fx:longint; 
      begin
            anc[u]:=u; 
            p:=h[u]; 
            while p<>0 do
            begin
                  v:=e[p].v; 
                  LCA(v); 
                  union(u,v); 
                  anc[getf(u)]:=u; 
                  p:=e[p].n; 
            end; 
            vis[u]:=true; 
            p:=hx[u]; 
            while p<>0 do
            begin
                  v:=g[p].v; 
                  if vis[v] then
                  begin
                        fx:=anc[getf(v)]; 
                        ans[b[u]]:=max(ans[b[u]],dep[u]+dep[v]-dep[fx]*2); 
                  end; 
                  p:=g[p].n; 
            end; 
  
      end; 
  
begin
      readln(n,k); 
      for i:=1 to n do
      begin
            readln(b[i],fi); 
            add(fi,i); 
            if fi=0 then root:=i; 
      end; 
      Bfs(root); 
      for i:=1 to n do
      begin
            f[i]:=i; 
            addx(i,low[b[i]]); 
            addx(low[b[i]],i); 
      end; 
      LCA(root); 
      for i:=1 to k do writeln(ans[i]); 
end.
posted on 2011-08-14 10:45  exponent  阅读(352)  评论(1编辑  收藏  举报