Cod sursa(job #16012)

Utilizator cos_minBondane Cosmin cos_min Data 11 februarie 2007 22:48:12
Problema Radiatie Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.89 kb
#include <stdio.h>
#include <fstream>
using namespace std;

#define in "radiatie.in"
#define out "radiatie.out"
#define dim 15001
#define inf 1000000001

int a[3][30001]; 
int t[dim], niv[dim];
int n, m, k;

typedef struct nod {
        int vf, cost;
        bool ok;
        nod* next;
}*PNOD;

PNOD graph[dim];
bool sel[dim];

void ReadData();
void GG(int,int);
void Kruskal();
int Find(int);
void Union(int,int);
void Qsort(int,int);
void Add(int,int,int);
int LCA(int,int);
void DF(int,int);

int main()
{
    ReadData();
    
    return 0;
}

void ReadData()
{
     int x,y,c;
     freopen(in,"r",stdin);
     freopen(out,"w",stdout);
     
     scanf("%d%d%d",&n,&m,&k);
     
     for ( int i = 1; i <= m; i++ )
     {   
         scanf("%d%d%d",&y,&x,&c);
         a[0][i] = x;
         a[1][i] = y;
         a[2][i] = c;
         Add(x,y,c);
         Add(y,x,c);
     }
     Qsort(1,m);
     Kruskal();
     
     DF(1,0);
     
     for ( int i = 1; i <= k; i++ )
     {
         scanf("%d%d",&x,&y);
         printf("%d\n",LCA(x,y));
     }
}

int LCA(int x, int y)
{
    int maxim=-1, c=0;
    
    while ( t[x] != t[y] )
    {
          if ( niv[x] > niv[y] )
          {
               for ( PNOD q = graph[x]; q; q=q->next )
                   if ( t[x] == q->vf ) 
                   {
                        c = q->cost;
                        break;
                   }
                   
               if ( maxim < c ) maxim = c;
               x = t[x];
          }
          else
          {
              for ( PNOD q = graph[y]; q; q=q->next )
                   if ( t[y] == q->vf ) 
                   {
                        c = q->cost;
                        break;
                   }
         
               if ( maxim < c ) maxim = c;
               y = t[y];
          }
    }
    
    while ( x != y )
    {
          if ( niv[x] > niv[y] )
          {
               for ( PNOD q = graph[x]; q; q=q->next )
                   if ( t[x] == q->vf ) 
                   {
                        c = q->cost;
                        break;
                   }
                   
               if ( maxim < c ) maxim = c;
               x = t[x];
          }
          else
          {
              for ( PNOD q = graph[y]; q; q=q->next )
                   if ( t[y] == q->vf ) 
                   {
                        c = q->cost;
                        break;
                   }
         
               if ( maxim < c ) maxim = c;
               y = t[y];
          }
    }
    
    return maxim;
}

void Add(int i, int j, int c)
{
     PNOD q = new nod;
     q->vf = i;
     q->ok = 0;
     q->cost = c;
     q->next = graph[j];
     graph[j] = q;
}

void Qsort(int st, int dr)
{
     int i = st - 1;
     int j = dr + 1;
     int pivot = a[2][st];
     
     while ( i <= j )
     {
           do { i++; } while ( a[2][i] < pivot );
           do { j--; } while ( a[2][j] > pivot );
           if ( i <= j )
           {
                int aux = a[2][i];
                a[2][i] = a[2][j];
                a[2][j] = aux;
                
                int aux2 = a[0][i];
                a[0][i] = a[0][j];
                a[0][j] = aux2;
                
                int aux3 = a[1][i];
                a[1][i] = a[1][j];
                a[1][j] = aux3;
           }
     }
     
     if ( st < j ) Qsort(st,j);
     if ( i < dr ) Qsort(i,dr);
}

int Find(int x)
{
     if ( x != t[x] ) t[x] = Find(t[x]);
     return t[x];
}

void DF(int nod, int nivel)
{
     niv[nod] = nivel;
     sel[nod] = 1;
     
     for ( PNOD q = graph[nod]; q; q=q->next )
     {
         if ( !sel[q->vf] && q->ok == 1 )
         {
              t[q->vf] = nod;
              DF(q->vf,nivel+1);
         }
     }
         
}

void Union(int x, int y)
{
     if ( x != y )
     {
          if ( niv[x] > niv[y] ) t[y] = x;
          else
          {
              t[x] = y;
              if ( niv[x] == niv[y] ) niv[y]++;
          }
     }
     
}

void Kruskal()
{
     for ( int i = 1; i <= n; i++ ) niv[t[i]=i] = 0;  
     
     int k = 0;
     
     for ( int i = 1; i <= m; i++ )
     {
         int r1 = Find(a[0][i]);
         int r2 = Find(a[1][i]);
         
         if ( r1 != r2 )
         {
              GG(a[0][i],a[1][i]);
              k++;
              Union(r1,r2);
              if ( k == n-1 ) break;
         }
     }
     
     for ( int i = 1; i <= n; i++ ) niv[t[i]=i] = 0;
}

void GG(int i, int j)
{
     for ( PNOD q = graph[i]; q; q=q->next )
         if ( q->vf == j )
         {
              q->ok = 1;
              break;
         } 
     
     for ( PNOD q = graph[j]; q; q=q->next )
         if ( q->vf == i )
         {
              q->ok = 1;
              break;
         }
}