Cod sursa(job #7354)

Utilizator mockeBarca Cristian Mihai mocke Data 21 ianuarie 2007 13:30:26
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.37 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX(a, b) ( (a) < (b) ? (b) : (a) )
#define MIN(a, b) ( (a) > (b) ? (b) : (a) )
#define NMAX 15024
#define MMAX 14
#define INF 1000000000

struct per1 { int a, b, c; } A[NMAX];
int Mat[NMAX][25], minv[NMAX][MMAX];
int Cost[NMAX][25], minpos[NMAX][MMAX];
int t[MMAX];
int High[MMAX];
int viz[NMAX], euler[4*NMAX], st[NMAX], poz[NMAX], put[4*NMAX];
int i, j, N, M, P, K;
int rx, ry, x, y, lung;
int a, b, repr;

int cmp (const void * a, const void * b)
{
     per1 x = *(per1*)a;
     per1 y = *(per1*)b;

     return x.c - y.c;
}


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 nod)
{
     int i, k = 0, elem;
     memset(viz, 0, sizeof(viz));
     lung = 0;

     st[++k] = nod;
     viz[nod] = 1;

     while (k > 0)
     {
          elem = -1;

          euler[++lung] = st[k];
          minv[lung][0] = k;
          minpos[lung][0] = lung;

          if (poz[euler[lung]] == 0) poz[euler[lung]] = lung;

          for (i = 1; i <= Mat[st[k]][0]; i++)
              if (!viz[Mat[st[k]][i]]) { elem = Mat[st[k]][i]; break; }

          if (elem > -1 && !viz[elem])
          {
               st[++k] = elem;
               viz[elem] = 1;
          }
          else
          st[k--]=0;
     }
}

int df2(int nod, int nod_c)
{
     int i, k = 0, elem, max;

     max = -INF;

     memset(viz, 0, sizeof(viz));

     st[++k] = nod;
     viz[nod] = 1;

     while (k > 0)
     {
          elem=-1;

          for (i = 1; i <= Mat[st[k]][0]; i++)
              if (!viz[Mat[st[k]][i]]) { elem = Mat[st[k]][i]; break; }

          if (elem > -1 && !viz[elem])
          {
               max = MAX(max, Cost[st[k]][i]);
               st[++k] = elem;
               viz[elem] = 1;

               if (elem == nod_c) break;
          }
          else
          st[k--]=0;
     }

     return max;
}

void precalc(int L)
{
     int q;

     for (q = 0, i = 1; i <= L; i++)
          if (i >= (1<<(q+1)) && i > (1<<q))  put[i] = q+1, q++;
              else  put[i] = q;
}

void RMQ()
{
     int logn = put[lung];

     for (j = 1; j <= logn; j++)
         for (i = 1; i <= (lung-(1<<j)+1); i++)
         {
               minv[i][j] = MIN(minv[i][j-1], minv[i+(1<<(j-1))][j-1]);

               if (minv[i][j] == minv[i][j-1])  minpos[i][j] = minpos[i][j-1];
               else minpos[i][j] = minpos[i+(1<<(j-1))][j-1];
         }
}

int LCA(int x, int y)
{
     int tt = put[y-x+1];

     int minim = MIN(minv[x][tt], minv[y-(1<<tt)+1][tt]);

     if (minim == minv[x][tt])
         return euler[minpos[x][tt]];

     return euler[minpos[y-(1<<tt)+1][tt]];
}

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

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

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

     for (i = 0; i < M; i++) scanf("%d %d %d\n", &A[i].a, &A[i].b, &A[i].c);

     qsort(A, M, sizeof(per1), cmp);

     for (i = 0; i < M; i++)
     {

          rx = rep(A[i].a);
          ry = rep(A[i].b);

          if (rx != ry)
          {
               uneste(rx, ry);

               Mat[A[i].a][++Mat[A[i].a][0]] = A[i].b;
               Cost[A[i].a][++Cost[A[i].a][0]] = A[i].c;

               Mat[A[i].b][++Mat[A[i].b][0]] = A[i].a;
               Cost[A[i].b][++Cost[A[i].b][0]] = A[i].c;
          }
     }

     df(1);

     precalc(lung);

     RMQ();

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

          if (a > b) repr = LCA(b, a);
          else repr = LCA(a, b);

          if (repr != a && repr != b)
          {
               int min1 = df2(repr, a);
               int min2 = df2(repr, b);
               printf("%d\n", MIN(min1, min2) );
          }

          if (repr == a && repr != b)
          {
               int min1 = df2(repr, b);
               printf("%d\n", min1);
          }

          if (repr == b && repr != a)
          {
               int min1 = df2(repr, a);
               printf("%d\n", min1);
          }

     }

     fclose(stdin);
     fclose(stdout);
     return 0;
}