Cod sursa(job #7786)

Utilizator love_for_uSpancioc Riana love_for_u Data 22 ianuarie 2007 17:35:05
Problema Radiatie Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.35 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#define PB push_back
#define MAX(a, b) ( (a) < (b) ? (b) : (a) )
#define MIN(a, b) ( (a) > (b) ? (b) : (a) )
#define INF 1000000
#define NMAX 15012

using namespace std;

struct per {int x, y, z;} V[NMAX];

vector <int> A[NMAX], C[NMAX];

int T[20][NMAX], Dmax[20][NMAX];
int used[NMAX], St[NMAX];
int in[NMAX], out[NMAX];
int rx, ry, t[NMAX], High[NMAX];
int i, j, k, N, M, logN, K;
int a, b;

int e_stramos(int i, int j)
{
     return (in[i] <= in[j]  && in[j] < out[j] && out[j] <= out[i]);
}

bool operator < (const per &A, const per &B)
{
		return A.z < B.z;
}

int rep(int x)
{
     return t[x] = (t[x] == x ? x : rep(t[x]));
}

void uneste(int rx, int ry)
{
     if (High[rx] > High[ry]) t[ry] = rx;
     else
     if (High[rx] < High[ry]) t[rx] = ry;
     else
     t[ry] = rx, High[rx]++;
}

void DF(int source)
{
     int elem, i, Tt = 0;

     St[0] = source;

     St[++k] = source;
     used[source] = 1;
     Dmax[0][source] = -INF;
     in[source] = ++Tt;

     while (k > 0)
     {
          elem = -1;
		  
		  int sz = A[St[k]].size();

          for  (i = 0; i < sz; i++)
               if ( !used[ A[St[k]][i] ] )
               {
                    elem = A[St[k]][i];
                    break;
               }

          if (elem > -1 && !used[elem])
          {
               Dmax[0][elem] = C[St[k]][i];
               St[++k] = elem;
               used[elem] = 1;
               in[elem] = ++Tt;
          }
          else
          {
               T[0][St[k]] = St[k-1];
               out[St[k]] = ++Tt;
               St[k--] = 0;
          }
     }
}

int calc_dist(int x, int y)
{
     int k, stramos = x, dist = -INF;
     int xp = x;

     if (e_stramos(x, y)) return -INF;

     for (k = logN; k >= 0; k--)
         if (e_stramos(T[k][xp], y))
         {
               stramos = T[k][xp];
         }
         else
         {
               dist = MAX(dist, Dmax[k][xp]);
               xp = T[k][xp];
         }

     if (stramos != x)
         return MAX(dist, Dmax[0][xp]);

     return -INF;
}

int main()
{
     freopen("radiatie.in", "r",  stdin);
     freopen("radiatie.out", "w", stdout);

     scanf("%d %d %d", &N, &M, &K);

     logN = 0;

     while ( (1<<logN + 1) < N) logN ++;
	 
	 for (i = 1; i <= N; i++) t[i] = i, High[i] = 0;

     for (i = 0; i < M; i++) scanf("%d %d %d", &V[i].x, &V[i].y, &V[i].z);
	 	    
	 sort(V, V+M);
	 
	 for (i = 0; i < M; i++)
	 {
		rx = rep(V[i].x);
		ry = rep(V[i].y);

		if (rx != ry)
		{
			uneste(rx, ry);
			
			A[V[i].x].PB(V[i].y);
			A[V[i].y].PB(V[i].x);
			C[V[i].x].PB(V[i].z);
			C[V[i].y].PB(V[i].z);
		}
	 }
		
     DF(1);

     in[0] = -INF;
     out[0] = +INF;

     for (k = 1; k <= logN; k++)
         for (i = 1; i <= N; i++)
             if (used[i] == 1)
             {
                    T[k][i] = T[k-1][ T[k-1][i] ];

                    Dmax[k][i] = MAX( Dmax[k-1][i], Dmax[k-1][ T[k-1][i] ] );
             }

    for (i = 1; i <= K; i++)
    {
          scanf("%d %d", &a, &b);

          int s1 = calc_dist(a, b);
          int s2 = calc_dist(b, a);

          printf("%d\n", MAX(s1, s2));
     }


     fclose(stdin);
     fclose(stdout);

     return 0;

}