Cod sursa(job #7195)

Utilizator vladcyb1Vlad Berteanu vladcyb1 Data 21 ianuarie 2007 13:03:00
Problema Radiatie Scor 100
Compilator fpc Status done
Runda preONI 2007, Runda 1, Clasele 11-12 Marime 5.8 kb

  const
       FIN = 'radiatie.in';
       FOUT = 'radiatie.out';
       NMAX = 30010;
       LOGMAX = 15;
       MMAX = 30000;

  type
       RMQ  = array[ 0..LOGMAX, 1..NMAX ] of longint;
       int = array[ 1..NMAX ] of longint;
       edge = record x, y, c : longint; end;
       edge_array = array[ 1..MMAX ] of edge;
       ref = ^cell;
       cell = record inf, c : longint; urm : ref; end;

  var
      LCA, RMAX, LCAP, A, COST : RMQ;
      V : edge_array;
      ind, H, Tata, PUT, SEL : int;
      E : array[ 1..NMAX ] of ref;
      ST, POZITIE, NOD, ADD, LEVEL : array[ 1..NMAX ] of longint;
      ADRESA : array[ 1..NMAX + 1 ] of ref;
      f, g : text;
      N, M, K, pivot, kt, ii, x, y  : longint;

  procedure read_data;
   var i : longint;
   begin
    assign( f, FIN ); reset( f );
    readln( f, N, M, Kt );
    for i := 1 to M do readln( f, V[i].x, V[i].y, V[i].c );
    for i := 1 to M do ind[i] := i;
  end;

 procedure poz( lo, hi : longint );
  var i, j, di, dj, aux : longint;
    begin
      i := lo; j := hi; di := 0; dj := - 1;
        while i < j do
          begin
            if V[ind[i]].c > V[ind[j]].c
                                     then
                                         begin
                                           aux := ind[i]; ind[i] := ind[j]; ind[j] := aux;
                                           aux := di; di := - dj; dj := - aux;
                                         end;
            i := i + di;
            j := j + dj;
          end;
    pivot := i;
  end;

 procedure quick( lo, hi : longint );
  begin
   if lo < hi  then
      begin
        poz( lo, hi );
        quick( lo, pivot - 1 );
        quick( pivot + 1, hi );
        end;
  end;

 function find( x : longint ) : longint;
  var r, i, j : longint;
  begin
   r := x;
    while H[r] <> r do r := H[r];
    i := x;
    while i <> r do
     begin
       j := H[i];
       H[i] := r;
       i := j;
     end;
   find := r;
   end;

 procedure merge( a, b : longint );
  begin
   H[b] := a;
  end;

  procedure add1( var p : ref; x, cost : longint );
   var q : ref;
   begin
    new( q ); q^.inf := x; q^.c := cost; q^.urm := p; p := q;
   end;


 procedure APM;
  var i, r1 ,r2, nr : longint;
  begin
   quick( 1, M );
   nr := 1;
   for i := 1 to N do H[i] := i;
   merge( V[ ind[1] ].x, V[ ind[1] ].y );
   add1( E[ V[ind[1] ].x ], V[ind[1]].y, V[ind[1]].c );
   add1( E[ V[ind[1] ].y ], V[ind[1]].x, V[ind[1]].c );

   i := 2;
    while ( i <= m ) and ( nr < n - 1 ) do
      begin
        r1 := find( V[ ind[i] ].x );
        r2 := find( V[ ind[i] ].y );
        if r1 <> r2 then
                  begin
                    merge( r1, r2 );
                    inc( nr );
                    add1( E[ V[ind[i] ].x ], V[ind[i]].y, V[ind[i]].c );
                    add1( E[ V[ind[i] ].y ], V[ind[i]].x, V[ind[i]].c );
                 end;
        inc( i );
     end;
  end;

procedure dfspec(nodd,niv:longint);
var temp:ref;
begin
 inc(k); NOD[k]:= nodd; add[k]:=niv; sel[nodd]:=1; pozitie[nodd]:=k;
 Level[nodd ] := niv;
  temp:=E[nodd];
   while temp<>nil do
    begin
     if sel[temp^.inf]=0 then
     begin
     TATA[ temp^.inf ] := nodd;
     COST[0][ temp^.inf ] := temp^.c;
     dfspec(temp^.inf,niv+1);
     inc(k); NOD[k]:=nodd; add[k]:=niv;
     end;
     temp:=temp^.urm;
    end;

end;


 function MAX( a, b : longint ) : longint;
  begin
   if a > b then MAX := a else MAX := b;
  end;

 procedure RMQ_u;
  var k, i, j : longint;
  begin
   k := 2 * n - 1;


  for i := 1 to N do A[0][i] := TATA[i];

 for i := 1 to LOGMAX do
   for j := 1 to N do
       begin
          A[i][j] := A[ i-1, A[i-1][j] ];
          COST[i][j] := MAX( COST[i-1][j], COST[i-1][ A[i-1][j] ] );
       end;

  for  i := 1 to k do begin LCA[0][i] := ADD[i]; LCAP[0][i] := NOD[i]; end;


  for i := 1 to LOGMAX do
    for j := 1 to k do
     if ( j + ( 1 shl i ) ) <= K then
           if LCA[i-1][j] < LCA[i-1][ j + ( 1 shl (i-1) ) ] then
              begin
                 LCA[i][j] := LCA[i-1][j];
                 LCAP[i][j] := LCAP[i-1][j];
               end
             else
               begin
                 LCA[i][j] := LCA[i-1][ j + ( 1 shl ( i-1) ) ];
                 LCAP[i][j] := LCAP[i-1][ j + ( 1 shl (i-1) ) ];
               end;

    for i := 0 to LOGMAX do
     if 1 shl i <= k then put[ 1 shl i ] := i;
    for i := 3 to k do
      if put[i] = 0 then put[i] := put[i-1];
  end;

  function MIN( a, b : longint ) : longint;
   begin
    if a < b then MIN := a else MIN := b;
   end;

 procedure query( a1, b : longint );
  var r1, r2, aux, pow, max1, max2, dif, xp, nod1 : longint;
  begin
    r1 := pozitie[a1]; r2 := pozitie[b];
    if r1 > r2 then begin aux := r1; r1 := r2; r2 := aux; end;
    pow := PUT[ r2 - r1 + 1 ];
    if LCA[ pow ][ r1 ] < LCA[ pow ][ r2 - ( 1 shl pow ) + 1 ]
      then nod1 := LCAP[pow][r1]
       else nod1 := LCAP[ pow][ r2 - ( 1 shl pow ) + 1 ];

    dif := abs(Level[nod1] - Level[a1]);
    max1 := 0;
    xp := a1;
    while dif > 0 do
      begin
        pow := Put[dif];
        max1 := MAX( max1, COST[ pow][ xp ] );
        xp := A[pow][xp];
        dif := dif - ( 1 shl pow );
      end;

    dif := abs(Level[nod1] - Level[b]);
    max2 := 0;
    xp := b;
     while dif > 0 do
       begin
        pow := Put[dif];
        max2 := MAX( max2, COST[ pow][xp] );
        xp := A[ pow, xp ];
        dif := dif - ( 1 shl pow );
       end;
    writeln( g, MAX( max1, max2 ) );
 end;

 begin
  read_data;
  APM;
  DFspec( 1, 0 );
  Tata[1] := 1; Cost[0][1] := 0;
  RMQ_u;
  assign( g, FOUT ); rewrite( g );
  for ii := 1 to kt do
    begin
     readln( f, x, y );
     query( x, y );
    end;
  close( g );
 end.