Cod sursa(job #7164)

Utilizator pelaspateSorin Fagateanu pelaspate Data 21 ianuarie 2007 12:56:29
Problema Radiatie Scor 100
Compilator fpc Status done
Runda preONI 2007, Runda 1, Clasele 11-12 Marime 3.92 kb
{idee minim...cu dfs...ar fi mers maxim in locurile alea?}
{$q-,r-,s-,d-,i-}
const maxn=15006;maxmuc=maxn*2;
var t,tout:Text;
   X,Y,C,O,V,Cost:array[0..maxmuc]of longint;
   Grad,Nivel:array[0..maxn]of longint;
   Maxim,Tata:array[0..15,0..maxn]of longint;
   sstep,test,loc,n,m,k,i,cuplat,pa,pb:longint;
   function max(a,b:longint):longint;begin if a>b then max:=a else max:=b;end;
   procedure mergesort(lo,hi:longint;var a,b:array of longint);
   var i,j,lg,juma:longint;
   begin
      if lo=hi then A[lo]:=lo else
      begin
         juma:=(lo+hi)div 2;mergesort(lo,juma,b,a);mergesort(juma+1,hi,b,a);
         i:=lo;j:=juma+1;
         for lg:=lo to hi do if(j>hi)or(i<=juma)and(C[B[i]]<=C[B[j]]) then
         begin A[lg]:=b[i];inc(i);end else begin A[lg]:=B[j];inc(j);end;
      end;
   end;
   function getSet(x:longint):longint;
   var aux,return,cine:longint;
   begin
      return:=x;while Nivel[return]<>return do return:=Nivel[return];
      cine:=x;
      while Nivel[cine]<>return do
      begin aux:=Nivel[cine];Nivel[cine]:=return;cine:=aux;end;
      getSet:=return;
   end;
   procedure union(x,y:longint);
   begin
      if V[x]>V[y] then Nivel[y]:=x else Nivel[x]:=y;
      if V[x]=V[y] then inc(V[y]);
   end;
   Procedure Bfs;
   var i,lo,hi:longint;
   begin
      fillchar(nivel,sizeof(nivel),0);nivel[1]:=1;lo:=1;hi:=1;C[1]:=1;
      while lo<=hi do
      begin
         for i:=Grad[C[lo]]+1 to grad[C[lo]+1] do
         if nivel[V[i]]=0 then
         begin
            inc(hi);C[hi]:=V[i];nivel[V[i]]:=nivel[C[lo]]+1;
            Tata[0,V[i]]:=c[lo];
            Maxim[0,v[i]]:=Cost[i];
         end;
         inc(lo);
      end;
   end;
   procedure build;
   begin
      sstep:=1;
      while 1 shl sstep<=N do
      begin
         for i:=1 to N do
         begin
            Tata[sstep,i]:=tata[sstep-1,tata[sstep-1,i]];
            Maxim[sstep,i]:=max(Maxim[sstep-1,tata[sstep-1,i]],Maxim[sstep-1,i]);
         end;
         inc(sstep);
      end;
   end;
   function get_lca(pa,pb:longint):longint;
   var dif,step,a,b,return:longint;
   begin
      return:=-maxlongint;a:=pa;b:=pb;
      if nivel[a]<nivel[b] then begin step:=a;a:=b;b:=step;end;
      if nivel[a]>nivel[b] then
      begin
         dif:=nivel[a]-nivel[b];step:=0;
         while 1 shl step<=dif do
         begin
            if (dif shr step)and 1=1 then
            begin
               return:=max(return,maxim[step,a]);
               a:=tata[step,a];
            end;
            inc(step);
         end;
      end;
      if a<>b then
      begin
         for step:=sstep downto 0 do
         if Tata[step,a]<>tata[step,b] then
         begin
            return:=max(return,max(Maxim[step,a],Maxim[step,b]));
            a:=tata[step,a];b:=tata[step,b];
         end;
         return:=max(return,max(Maxim[0,a],Maxim[0,b]));
      end;
      get_lca:=return;
   end;
{   var t1:longint;t2:longint absolute $0:$046c;}
begin
{   t1:=t2;}
   assign(t,'radiatie.in');reset(T);readln(t,n,m,k);
   assign(tout,'radiatie.out');rewrite(Tout);
   for i:=1 to M do begin readln(T,X[i],Y[i],C[i]);end;Mergesort(1,M,O,V);
   fillchar(v,sizeof(v),0);for i:=1 to N do Nivel[i]:=i;
   for i:=1 to M do
   begin
      pa:=getSet(X[O[i]]);pb:=getSet(Y[O[i]]);
      if pa<>pb then
      begin
         union(pa,pb);inc(cuplat);
         inc(Grad[X[O[i]]]);inc(grad[Y[O[i]]]);
         O[i]:=-O[i];
      end;
      if cuplat=N-1 then break;
   end;for i:=1 to N+1 do inc(grad[i],grad[i-1]);
   for i:=1 to M do if O[i]<0 then
   begin
      loc:=Grad[X[-O[i]]];
      V[loc]:=Y[-O[i]];Cost[loc]:=C[-O[i]];dec(GRad[x[-O[i]]]);
      loc:=Grad[Y[-O[i]]];
      V[loc]:=X[-O[i]];Cost[loc]:=C[-O[i]];dec(GRad[Y[-O[i]]]);
   end;Bfs;Build;
   for test:=1 to K do
   begin
      readln(t,pa,pb);
      writeln(tout,get_lca(pa,pb));
   end;
   close(T);close(Tout);
{   writeln((t2-t1)/18.2:0:6);}
end.