Cod sursa(job #177769)

Utilizator vlad_popaVlad Popa vlad_popa Data 13 aprilie 2008 16:31:18
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.46 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

#define ii pair <int, int>
#define MAXN 15005
#define x first
#define y second
#define mp make_pair
#define pb push_back

int N, M, K;
vector < pair <int, ii> > edge;
int r[MAXN], h[MAXN];
vector <int> f[MAXN];
ii str[15][MAXN], p[MAXN];
int cd[MAXN];

int cmp (pair <int, ii> a, pair <int, ii> b)
{
    return a.x < b.x;
}

void read ()
{
    int a, b, c, i;
    for (scanf (" %d %d %d", &N, &M, &K), i = 0; i < M; ++ i)
    {
        scanf (" %d %d %d", &a, &b, &c);
        edge.pb(mp(c, mp(a, b)));
    }
    sort (edge.begin(), edge.end(), cmp);
}

int root (int n)
{
    if (r[n] != n)
        return r[n] = root(r[n]);
    return n;
}

void unite (int a, int b, int n1, int n2, int cost)
{
    if (h[n1] > h[n2])
    {
        r[n2] = n1;
        p[a] = mp(b, cost);
        f[b].pb(a);
    }
    else
    {
        r[n1] = n2;
        p[b] = mp(a, cost);
        f[a].pb(b);
        if (h[n2] == h[n1])
            ++ h[n1];
    }
}

void Kruskal ()
{
    int i, cnt = 1;
    for (i = 1; i <= N; ++ i)
        r[i] = i;
    
    for (i = 0; cnt < N; ++ i)
    {
        int r1 = root(edge[i].y.x), r2 = root(edge[i].y.y);
        if (r1 != r2)
        {
            ++ cnt;
            unite(edge[i].y.x, edge[i].y.y, r1, r2, edge[i].x);
        }
    }
}

void BFS (int s)
{
    int ended, pas, i, sz, nod;
    cd[ended = 0] = s;
    h[s] = 0;
    
    for (pas = 0; pas <= ended; ++ pas)
    {
        nod = cd[pas];
        for (i = 0, sz = f[nod].size(); i < sz; ++ i)
        {
            h[f[nod][i]] = h[nod] + 1;
            cd[++ ended] = f[nod][i];
        }
    }
}

int Min_Path (int a, int b)
{
    int i, Max = 0;
    if (h[a] < h[b]) 
    {
        int dif = h[b] - h[a];
        for (i = 0; (1<<i) <= N; ++ i)
            if (dif & (1 << i))
            {
                Max = max (str[i][b].y, Max);
                b = str[i][b].x;               
            }
    }
    if (h[a] > h[b]) 
    {
        int dif = h[a] - h[b];
        for (i = 0; (1<<i) <= N; ++ i)
            if (dif & (1 << i))
            {
                Max = max (str[i][a].y, Max);
                a = str[i][a].x;               
            }
    }
    while (a != b)
    {
        for (i = 0; str[i][a].x != str[i][b].x; ++ i);
        if (i)
        {
            Max = max (Max, str[i-1][a].y); Max = max (Max, str[i-1][b].y); 
            a = str[i-1][a].x; b = str[i-1][b].x;
        }
        else
        {
            Max = max (Max, str[0][a].y); Max = max (Max, str[0][b].y); 
            a = str[0][a].x; b = str[0][b].x;
        }
    }
    
    return Max;
}

void solve ()
{
    int i, j;
    
    Kruskal();
    
    for (i = 1; i <= N; ++ i)
        if (!p[i].x)
            BFS (i);
    
    for (i = 1; i <= N; ++ i)
        str[0][i] = p[i];
    for (i = 1; (1<<i) <= N; ++ i)
        for (j = 1; j <= N; ++ j)   
        {
            str[i][j].x = str[i-1][str[i-1][j].x].x;
            str[i][j].y = max (str[i-1][j].y, str[i-1][str[i-1][j].x].y);
        }
        
    int a, b;
    for (i = 1; i <= K; ++ i)
    {
        scanf (" %d %d", &a, &b);
        printf ("%d\n", Min_Path(a, b));
    }
}

int
 main ()
{
    freopen ("radiatie.in", "rt", stdin);
    freopen ("radiatie.out", "wt", stdout);
    
    read ();
    solve ();
    
    return 0;
}