Cod sursa(job #14962)

Utilizator victorsbVictor Rusu victorsb Data 10 februarie 2007 13:14:40
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

#define Nmax 15005
#define Kmax 15005
#define Mmax 30005
#define pb push_back
#define mp make_pair
#define cost first
#define y second.first
#define x second.second
#define nod second

int n, m, k;
int ind[Mmax], h[Nmax], t[Nmax], tata[Nmax], v[Nmax], ad[Nmax], str[Nmax][16], smax[Nmax][16];
pair<int, pair<int, int> > muchie[Mmax];
vector<pair<int, int> > lv[Nmax];

inline void citire()
{
    int i;
    scanf("%d %d %d\n", &n, &m, &k);
    for (i=1; i<=m; ++i)
        scanf("%d %d %d\n", &muchie[i].x, &muchie[i].y, &muchie[i].cost);
}

void uneste(int a, int b)
{
    if (h[a] < h[b])
        t[a] = b;
    else
        t[b] = a;
    if (h[a] == h[b])
        ++h[a];
}

int find(int a)
{
    if (t[a] != a)
        t[a] = find(t[a]);
    return t[a];
}

inline int cmp(const int a, const int b)
{
    return (muchie[a].cost < muchie[b].cost);
}

void kruskal()
{
    int i;
    for (i=1; i<=m; ++i)
        ind[i] = i;
    sort(ind + 1, ind + m + 1, cmp);
    for (i=1; i<=n; ++i)
        t[i] = i;
    for (i=1; i<=m; ++i)
        if (find(muchie[ind[i]].x) != find(muchie[ind[i]].y))
        {
            lv[muchie[ind[i]].x].pb(mp(muchie[ind[i]].cost, muchie[ind[i]].y));
            lv[muchie[ind[i]].y].pb(mp(muchie[ind[i]].cost, muchie[ind[i]].x));
            uneste(find(muchie[ind[i]].x), find(muchie[ind[i]].y));
        }
}

void df(int nod, int vl)
{
    vector<pair<int,int> > :: iterator it;
    v[nod] = 1;
    ad[nod] = vl;
    for (it = lv[nod].begin(); it != lv[nod].end(); ++it)
        if (!v[it->nod])
        {
            tata[it->nod] = nod;
            smax[it->nod][0] = it->cost;
            df(it->nod, vl+1);
        }
}

int query(int a, int b)
{
    int max1 = 0, max2 = 0, i;
    if (ad[b] > ad[a])
        swap(a, b);
    if (ad[a] > ad[b])
    {
        for (i=15; i>=0; --i)
            if (ad[a] - ad[b] >= (1 << i))
            {
                max1 = max(max1, smax[a][i]);
                a = str[a][i];
            }
    }
    if (a == b)
        return max1;
    for (i=15; i>=0; --i)
        if (ad[a] > (1 << i))
        {
            if (str[a][i] == str[b][i])
                max2 = max(smax[a][i], smax[b][i]);
            else
            {
                max1 = max(max1, max(smax[a][i], smax[b][i]));
                a = str[a][i];
                b = str[b][i];
            }
        }
    return max(max1, max2);
}

void solve()
{
    int i, j;
    kruskal();
    for (i=1; i<=n; ++i)
        if (!v[i])
            df(i, 1);
    for (i=1; i<=n; ++i)
        str[i][0] = tata[i];
    for (j=1; (1<<j)<n; ++j)
        for (i=1; i<=n; ++i)
            if (ad[i] > (1 << j))
                str[i][j] = str[str[i][j-1]][j-1];
    
    for (j=1; (1<<j)<n; ++j)
        for (i=1; i<=n; ++i)
            if (ad[i] > (1 << j))
                smax[i][j] = max( smax[i][j-1], smax[str[i][j-1]][j-1]);
}

void interog()
{
    int i, a, b;
    for (i=1; i<=k; ++i)
    {
        scanf("%d %d\n", &a, &b);
        printf("%d\n", query(a, b));
    }
}

int main()
{
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    citire();
    solve();
    interog();
    return 0;
}