Cod sursa(job #7672)

Utilizator filipbFilip Cristian Buruiana filipb Data 21 ianuarie 2007 21:35:40
Problema Radiatie Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 3.2 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max(a, b) ((a > b) ? a : b)
#define LG 16
#define NMax 15024
typedef struct lista { int id, cost; struct lista *next; } lista;
typedef lista *Graf[NMax]; 
typedef struct { int x, y, cst; } muchie;

int N, M, K, bst = 0, tata[NMax], rang[NMax];
Graf G;
muchie v[30005]; int h = 0;
int S[LG][NMax], D[LG][NMax], dep[NMax], lg[NMax];

void add_to_list(lista **l, int item, int cst)
{
     lista *tmp = (lista *)malloc(sizeof(lista));
     
     tmp->id = item;
     tmp->cost = cst;
     tmp->next = *l;
     *l = tmp;
}

int cmp(const void *a, const void *b)
{
    muchie *A = (muchie *)a, *B = (muchie *)b;
    
    return A->cst - B->cst;
}

int find_multime(int x)
{
    if (x != tata[x])
       tata[x] = find_multime(tata[x]);
    return tata[x];
}

int uneste(int x, int y)
{
    if (rang[x] > rang[y])
       tata[y] = x;
    else
    {
        tata[x] = y;
        if (rang[x] == rang[y])
           rang[y]++;
    }
    
}

void dfs(int nod)
{
     int i, j;
     lista *f;
     
     for (i = 1; i <= lg[dep[nod]]; i++)
         S[i][nod] = S[i-1][S[i-1][nod]],
         D[i][nod] = max(D[i-1][nod], D[i-1][S[i-1][nod]]);
     
     for (f = G[nod]; f; f = f->next)
         if (tata[f->id] == -1)
         { tata[f->id] = nod; S[0][f->id] = nod; 
           D[0][f->id] = f->cost;
           dep[f->id] = dep[nod]+1; dfs(f->id); }
         
}

int query(int x, int y)
{
    int i, mx = -100000;
    
    for (; dep[x] > dep[y]; x = S[lg[dep[x]-dep[y]]][x])
        mx = max(mx, D[lg[dep[x]-dep[y]]][x]);
    for (; dep[y] > dep[x]; y = S[lg[dep[y]-dep[x]]][y])
        mx = max(mx, D[lg[dep[y]-dep[x]]][y]);
    if (x == y) return mx;
        
    for (i = lg[dep[x]]; i >= 0; i--)
        if (S[i][x] != S[i][y])
           mx = max(mx, max(D[i][x], D[i][y])),
           x = S[i][x], y = S[i][y];
           
    mx = max(mx, max(D[0][x], D[0][y]));
    
    return mx;
}

int main(void)
{
    int i, j, c, i1, i2;
    
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    
    scanf("%d %d %d", &N, &M, &K);
    for (i = 1; i <= N; i++) G[i] = NULL;
    
    for (i = 2; i <= N; i++)
        lg[i] = 1 + lg[i/2];
    
    for (; M; M--)
    {
        scanf("%d %d %d", &i, &j, &c);
        v[h].x = i; v[h].y = j; v[h].cst = c; h++;
    }
    qsort(v, h, sizeof(muchie), cmp);
    
    for (i = 1; i <= N; i++) tata[i] = i, rang[i] = 1;
    
    for (i = 0; i < h; i++)
    {
        i1 = find_multime(v[i].x);
        i2 = find_multime(v[i].y);
        
        if (i1 != i2)
        {
               uneste(i1, i2);
               add_to_list(&G[v[i].x], v[i].y, v[i].cst);
               add_to_list(&G[v[i].y], v[i].x, v[i].cst);
//               printf("%d %d\n", v[i].x, v[i].y);
        }
             
    }
    
    memset(tata, -1, sizeof(tata));
    for (i = 1; i <= N; i++)
        if (tata[i] == -1)
        {
           tata[i] = 0; dep[i] = 0;
           dfs(i);
        }    

    for (; K; K--)
    {
        scanf("%d %d", &i, &j);
        printf("%d\n", query(i, j));
    }    
    
    return 0;
}