Cod sursa(job #2884070)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 2 aprilie 2022 12:52:40
Problema Radiatie Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.68 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

const string filename = "radiatie";
ifstream fin(filename + ".in");
ofstream fout(filename + ".out");

const int maxN = 15005, inf = 0x3f3f3f3f;
int n, m, k, nrb, ind_euler;
int root[maxN], depth_dsu[maxN], log2[2 * maxN], poz_euler[maxN], euler[maxN], depth[maxN];
int rmq[17][maxN], c[17][maxN], s[17][maxN];
bool used[maxN];
struct muchie {
    int nod, cost;
};
vector <muchie> initG[maxN], G[maxN];
struct lista_muchii {
    int x, y, cost;
    bool operator < (const lista_muchii &other) const
    {
        return cost < other.cost;
    }
};
vector <lista_muchii> v;

int findroot(int x)
{
    if(root[x] == 0)
        return x;
    return findroot(root[x]);
}

void join(int x, int y)
{
    if(depth_dsu[x] > depth_dsu[y])
        root[y] = x;
    if(depth_dsu[x] < depth_dsu[y])
        root[x] = y;
    if(depth_dsu[x] == depth_dsu[y])
        root[y] = x, depth_dsu[x]++;
}

void dfs(int nod, int tata)
{
    //cout << nod << '\n';
    euler[++ind_euler] = nod;
    depth[nod] = depth[tata] + 1;
    poz_euler[nod] = ind_euler;
    for(auto nxt : G[nod])
    {
        if(nxt.nod != tata)
        {
            s[0][nxt.nod] = nod;
            for(int i = 1; i <= 15; i++)
                s[i][nxt.nod] = s[i - 1][s[i - 1][nxt.nod]];
            c[0][nxt.nod] = nxt.cost;
            for(int i = 1; i <= 15; i++)
                c[i][nxt.nod] = max(c[i - 1][nxt.nod], c[i - 1][s[i - 1][nxt.nod]]);
            dfs(nxt.nod, nod);
            euler[++ind_euler] = nod;
        }
    }
}

int lca(int x, int y)
{
    int st, dr, log, ans;
    st = min(poz_euler[x], poz_euler[y]);
    dr = max(poz_euler[x], poz_euler[y]);
    log = log2[dr - st + 1];
    if(depth[rmq[log][st]] < depth[rmq[log][dr - (1 << log) + 1]])
        return rmq[log][st];
    else
        return rmq[log][dr - (1 << log) + 1];
}

int main()
{
    fin >> n >> m >> k;
    for(int x, y, c, i = 1; i <= m; i++)
    {
        fin >> x >> y >> c;
        initG[x].push_back({y, c});
        initG[y].push_back({x, c});
        v.push_back({x, y, c});
    }
    /// apm
    sort(v.begin(), v.end());
    for(auto elem : v)
    {
        int rx = findroot(elem.x), ry = findroot(elem.y);
        if(rx == ry)
            continue;
        join(rx, ry);
        G[elem.x].push_back({elem.y, elem.cost});
        G[elem.y].push_back({elem.x, elem.cost});
    }
    /// rmq (pt lca) + c[i][j] = costul maxim de la i la stramosul 2^j
    for(int i = 2; i <= 2 * n; i++)
        log2[i] = log2[i / 2] + 1;
    dfs(1, 0);
    for(int i = 1; i <= ind_euler; i++)
        rmq[0][i] = euler[i];
    for(int j = 1; (1 << j) <= ind_euler; j++)
    {
        for(int i = 1; i - 1 + (1 << j) <= ind_euler; i++)
        {
            if(depth[rmq[j - 1][i]] < depth[rmq[j - 1][i + (1 << (j - 1))]])
                rmq[j][i] = rmq[j - 1][i];
            else
                rmq[j][i] = rmq[j - 1][i + (1 << (j - 1))];
        }
    }
    for(int x, y, i = 1; i <= k; i++)
    {
        fin >> x >> y;
        int z = lca(x, y), ans = 0, depth_diff;
        depth_diff = depth[x] - depth[z];
        for(int j = 0; (1 << j) <= depth_diff; j++)
            if(depth_diff & (1 << j))
            {
                ans = max(ans, c[j][x]);
                x = s[j][x];
            }
        depth_diff = depth[y] - depth[z];
        for(int j = 0; (1 << j) <= depth_diff; j++)
            if(depth_diff & (1 << j))
            {
                ans = max(ans, c[j][y]);
                y = s[j][y];
            }
        fout << ans << '\n';
    }
    return 0;
}