Cod sursa(job #2926987)

Utilizator mateitudordmDumitru Matei mateitudordm Data 19 octombrie 2022 09:40:23
Problema Radiatie Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

ifstream cin ("radiatie.in");
ofstream cout ("radiatie.out");

const int nmax = 15000, mmax = 30000;

struct edge
{
    int nod, cost;
};
vector<edge> ad[nmax + 1];

struct cell
{
    int a, b, c;
};
bool cmp_cost (cell x, cell y)
{
    return x.c < y.c;
}
cell muchii[mmax + 1];

int n, father[nmax + 1], set_size[nmax + 1], logg[nmax + 1];
int cost[nmax + 1], daddy[nmax + 1], bl[20][nmax + 1], bl_max[20][nmax + 1], lvl[nmax + 1];

void dfs (int nod, int dad)
{
    daddy[nod] = dad;
    lvl[nod] = lvl[dad] + 1;
    for (auto son : ad[nod])
        if (son.nod != dad)
            cost[son.nod] = son.cost, dfs (son.nod, nod);
}

int find_set (int x)
{
    if (father[x] == x)
        return x;
    return father[x] = find_set (father[x]);
}
void unite_sets (int x, int y)
{
    x = find_set (x);
    y = find_set (y);
    if (set_size[x] < set_size[y])
        swap (x, y);
    father[y] = x;
    set_size[x] += set_size[y];
}



void binary_lifting()
{
    int i, j;
    for (i = 1; i <= n; i++)
        bl[0][i] = daddy[i], bl_max[0][i] = cost[i];
    for (i = 1; i <= logg[n]; i++)
        for (j = 1; j <= n; j++)
        {
            bl[i][j] = bl[i - 1][bl[i - 1][j]];
            bl_max[i][j] = max (bl_max[i - 1][j], bl_max[i - 1][bl[i - 1][j]]);
        }

}

int get_max (int a, int b)
{
    if (lvl[a] < lvl[b])
        swap (a, b);
    int dif = lvl[a] - lvl[b], bit, maxx = 0, ok = 0;
    for (bit = 13; bit >= 0; bit--)
        if ((dif & (1 << bit)))
            maxx = max (maxx, bl_max[bit][a]), a = bl[bit][a], dif -= (1 << bit);
    for (bit = 13; bit >= 0; bit--)
        if (bl[bit][a] != bl[bit][b])
        {
            ok = 1;
            maxx = max (maxx, bl_max[bit][a]);
            maxx = max (maxx, bl_max[bit][b]);
            a = bl[bit][a];
            b = bl[bit][b];
        }
    if (ok == 1)
    {
        maxx = max (maxx, cost[a]);
        maxx = max (maxx, cost[b]);
    }
    return maxx;
}

int main()
{
    int m, k, a, b, c, i;

    cin >> n >> m >> k;

    for (i = 1; i <= m; i++)
        cin >> muchii[i].a >> muchii[i].b >> muchii[i].c;
    sort (muchii + 1, muchii + n + 1, cmp_cost);

    for (i = 1; i <= n; i++)
        father[i] = i;
    logg[1] = 1;
    for (i = 2; i <= n; i++)
        logg[i] = logg[i / 2] + 1;
    for (i = 1; i <= n; i++)
    {
        if (find_set (muchii[i].a) != find_set (muchii[i].b))
        {
            unite_sets (muchii[i].a, muchii[i].b);
            ad[muchii[i].a].push_back ({muchii[i].b, muchii[i].c});
            ad[muchii[i].b].push_back ({muchii[i].a, muchii[i].c});
        }
    }

    dfs (1, 0);
    binary_lifting();
    for (i = 1; i <= k; i++)
    {
        cin >> a >> b;
        cout << get_max (a, b) << '\n';
    }

    return 0;
}