Cod sursa(job #2308483)

Utilizator TheNextGenerationAyy LMAO TheNextGeneration Data 27 decembrie 2018 11:02:30
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("radiatie.in");
ofstream out("radiatie.out");
const int N = 15005;
const int L = 15;
int size[N],link[N],lvl[N],dp[L][N],c[L][N],n;
bool viz[N];
vector< tuple<int,int,int> > edges;
vector< pair<int,int> > v[N];
int find(int x)
{
    while (x!=link[x])
        x = link[x];
    return x;
}
void unite(int x, int y)
{
    x = find(x);
    y = find(y);
    if (size[y]>size[x])
        swap(x,y);
    size[x]+=size[y];
    link[y] = x;
}

void dfs(int x)
{
    for (auto it: v[x])
    {
        if (!lvl[it.first])
        {
            lvl[it.first] = 1+lvl[x];
            dfs(it.first);
            dp[0][it.first] = x;
            c[0][it.first] = it.second;
        }
    }
}
void buildDP()
{
    for (int i = 1; (1<<i)<=n; i++)
        for (int j = 1; j<=n; j++)
        {
            dp[i][j] = dp[i-1][dp[i-1][j]];
            c[i][j] = max(c[i-1][j],c[i-1][dp[i-1][j]]);
        }
}
int query(int x, int y)
{
    if (lvl[x]<lvl[y])
        swap(x,y);
    int L1 = 1, L2 = 1;
    while ((1<<L1)<lvl[x])
        L1++;
    while ((1<<L2)<lvl[y])
        L2++;
    int Max = 0;
    for (int i = L1; i>=0; i--)
        if (lvl[x]-(1<<i)>=lvl[y])
        {
            Max = max(Max,c[i][x]);
            x = dp[i][x];
        }
    if (x == y)
        return Max;
    for (int i = L2; i>=0; i--)
        if (lvl[x]-(1<<i)>=0 && dp[i][x]!=dp[i][y])
        {
            Max = max(Max,max(c[i][x],c[i][y]));
            x = dp[i][x];
            y = dp[i][y];
        }
    Max = max(Max,max(c[0][x],c[0][y]));
    return Max;
}
int main()
{
    int m,q;
    in >> n >> m >> q;
    for (int i = 1; i<=n; i++)
    {
        link[i] = i;
        size[i] = 1;
    }
    for (int i = 1; i<=m; i++)
    {
        int x,y,c;
        in >> x >> y >> c;
        edges.push_back(make_tuple(c,x,y));
    }
    sort(edges.begin(),edges.end());
    for (auto it: edges)
    {
        int cost = get<0>(it), x = get<1>(it), y = get<2>(it);
        if (find(x)!=find(y))
        {
            v[x].push_back({y,cost});
            v[y].push_back({x,cost});
            unite(x,y);
        }
    }
    dfs(1);
    buildDP();
    for (int i = 1; i<=q; i++)
    {
        int x,y;
        in >> x >> y;
        out << query(x,y) << "\n";
    }
}