Cod sursa(job #1592802)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 7 februarie 2016 22:54:00
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.22 kb
#include <bits/stdc++.h>

using namespace std;

const int Nmax = 15000 + 10;
const int Log = 13;

int n , m , k , i , x , y , cost;
int T[Nmax] , lvl[Nmax];
int tata[Nmax][Log+1] , dp[Nmax][Log+1];
vector < pair < int , pair < int , int > > > edge;
vector < pair < int , int > > g[Nmax];

int multime(int node)
{
    if (node != T[node]) T[node] = multime(T[node]);
    return T[node];
}

void dfs(int node , int dad , int m)
{
    lvl[node] = lvl[dad] + 1;
    tata[node][0] = dad; dp[node][0] = m;
    for (i = 1; (1 << i) <= lvl[node]; ++i)
    {
        tata[node][i] = tata[tata[node][i-1]][i-1];
        dp[node][i] = max(dp[node][i-1] , dp[tata[node][i-1]][i-1]);
    }

    for (auto &it : g[node])
    {
        if (it.first == dad) continue;
        dfs(it.first , node , it.second);
    }
}

int kanc(int x , int k , int &ret)
{
    for (int i = 0; i <= Log; ++i)
        if (k & (1 << i))
            ret = max(ret , dp[x][i]), x = tata[x][i];

    return x;
}

int drum(int x , int y)
{
    int ret = 0;

    if (lvl[x] < lvl[y]) swap(x , y);
    x = kanc(x , lvl[x] - lvl[y] , ret);

    if (x == y) return ret;

    for (i = Log; i >= 0; --i)
        if (tata[x][i] != tata[y][i])
        {
            ret = max(ret , max(dp[x][i] , dp[y][i]));
            x = tata[x][i], y = tata[y][i];
        }

    ret = max(ret , max(dp[x][0] , dp[y][0]));
    return ret;
}

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

    scanf("%d %d %d", &n, &m, &k);

    for (i = 1; i <= m; ++i)
    {
        scanf("%d %d %d", &x, &y, &cost);
        edge.push_back({cost,{x,y}});
    }

    sort(edge.begin() , edge.end());
    for (i = 1; i <= n; ++i) T[i] = i;

    for (i = 0; i < m; ++i)
    {
        cost = edge[i].first;
        tie(x , y) = edge[i].second;

        int p1 , p2;
        if ((p1 = multime(x)) != (p2 = multime(y)))
        {
            T[p2] = p1;
            g[x].push_back({y,cost});
            g[y].push_back({x,cost});
        }
    }

    lvl[0] = -1;
    dfs(1 , 0 , 0);

    for ( ; k ; --k)
    {
        scanf("%d %d", &x, &y);
        printf("%d\n", drum(x , y));
    }

    return 0;
}