Cod sursa(job #9523)

Utilizator vladcyb1Vlad Berteanu vladcyb1 Data 27 ianuarie 2007 16:01:09
Problema Amenzi Scor 0
Compilator fpc Status done
Runda Unirea 2007, clasele 11-12 Marime 3.71 kb

 const
      FIN = 'amenzi.in';
      FOUT = 'amenzi.out';
      NMAX = 150;
      VMAX = 3502;
      KMAX = 12000;

  type
      int_vmax = array[ 0..VMAX ] of longint;
      AIB = array[ 0..NMAX ] of int_vmax;
      int = array[ 0..KMAX ] of longint;
      matrix = array[ 0..NMAX, 0..NMAX ] of longint;

 var
     H : AIB;
     cnt : int_vmax;
     A : matrix;
     NOD, TIMP, ind : int;
     cost : array[ 1..NMAX, 0..VMAX ] of longint;
     f, g : text;
     N,M,K,P : longint;

 procedure read_data;
  var i, c, x, y, j : longint;
  begin
   assign( f, FIN ); reset( f );
   readln( f, N, M, K, P );

    for i := 1 to N do
     for j := 1 to N do A[i,j] := maxlongint div 2  - 100000 ;

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

   for  i := 1 to  M do
     begin
      readln( f, x , y, c );
      if a[x,y] > c then A[x,y] := c;
      a[y,x] := a[x,y];
     end;
   for i := 1 to k do
      begin
           readln( f, NOD[i], TIMP[i], c );
           inc( COST[ NOD[i], TIMP[i] ], c );
           end;
  end;

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

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

  procedure roy;
   var i, j, k : longint;
    begin
     for k := 1 to n do
      for i := 1 to n do
       for j := 1 to n do
          A[i,j] := MIN( A[i,j], A[i,k] + A[k,j] );
    end;

  procedure count_sort;
   var i : longint;
   begin
    for  i := 1 to K do inc( cnt[timp[i]] );
    for i := 1 to vmax do cnt[i] := cnt[i] + cnt[i-1];
    for i := 1 to K do
       begin
         ind[ cnt[timp[i] ] ] := i;
         dec( cnt[timp[i] ] );
       end;
   end;

  procedure update( var A : int_vmax; p, x : longint );
   var i : longint;
    begin
    if p = 0 then A[0] := MAX( A[0], x )
     else
     begin
    i:=p;
      while i <= VMAX do
        begin
         if a[i] < x then a[i] := x;
         i:=i+((i-1)xor(i))and(i);
        end;
      end;
    end;

   function query( var A : int_vmax; p : longint ) : longint;
     var i, max : longint;
        begin

         i:=p; max := -1;
          while i >= 1 do
            begin
            if max < a[i] then max := a[i];
            i:=i-((i-1)xor(i))and(i);
            end;
      if A[0] > max then max := A[0];
      query := max;
   end;


 procedure solve;
  var i, j, vv, maxim, tmp, x, y : longint;
   begin

      // trebuie sa dau amenzile din nodul 1

      for i := 1 to n do
       for j := 0 to Vmax do H[i,j] := -1;
      update( H[1], 0, 0 );
      update( H[1], 0, COST[ 1, 1 ] );

       for i := 1 to k do
         begin
          maxim := -1;
         for j := 1 to n do
            if A[ NOD[ind[i]], j ] > 0 then
               begin
                 tmp := TIMP[ind[i]] - A[ NOD[ind[i]], j ];
                 if tmp >= 0 then
                   begin
                     vv := query( H[j], tmp );
                     if vv <> - 1 then
                     maxim := MAX( maxim, vv + COST[ NOD[ind[i]], TIMP[ind[i]] ] );
                    end;
                end;
           update( H[ NOD[ind[i]] ], TIMP[ind[i]], maxim );
         end;

   assign( g, FOUT ); rewrite( g );

   for i := 1 to P do
     begin
       readln( f, x, y );  // x = nodul, y = timpul
        maxim := -1;
        for  j := 1 to n do
          begin
            tmp := y - A[ x, j ];
            if tmp >= 0 then  vv := query( H[j], tmp ) else vv := -1;
            maxim := MAX( maxim, vv );
          end;
        writeln( g, maxim );
   end;
   close( f ); close( g );
  end;

  begin
   read_data;
   roy;
   count_sort;
   solve;
  end.