Cod sursa(job #3315796)

Utilizator Ruxandra009Ruxandra Vasilescu Ruxandra009 Data 16 octombrie 2025 08:46:09
Problema Radiatie Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.29 kb
#include <algorithm>
#include <fstream>
#include <vector>

using namespace std;

const string txt = "radiatie";
const int nmax = 1e5;

ifstream f(txt + ".in");
ofstream g(txt + ".out");

struct ceva {
    int vec, c;
};

struct kr {
    int x, y, c;
};

struct aint {
    int n, val[4 * nmax];

    void upd(int poz, int x) { update(1, 1, n, poz, x); }
    int maxi(int x, int y) { return query(1, 1, n, x, y); }

    void update(int nod, int l, int r, int poz, int x)
    {
        if (l == r) { val[nod] = x; return; }
        int mid = (l + r) / 2;

        if (poz <= mid) update(2 * nod, l, mid, poz, x);
        else update(2 * nod + 1, mid + 1, r, poz, x);

        val[nod] = max(val[2 * nod], val[2 * nod + 1]);
    }

    int query(int nod, int l, int r, int x, int y)
    {
        if (x <= l && r <= y) return val[nod];
        int mid = (l + r) / 2;

        int ans = 0;
        if (x <= mid) ans = max(ans, query(2 * nod, l, mid, x, y));
        if (y > mid) ans = max(ans, query(2 * nod + 1, mid + 1, r, x, y));
        
        return ans;
    }

} a;

int n, m, q, num[nmax], r[nmax], p[nmax], deep[nmax], cnt[nmax], cost[nmax], t[nmax], bi[nmax][25];
vector<int> v[nmax];
vector<ceva> v2[nmax];
vector<kr> e;

static void dfs(int nod, int prev = 0)
{
    p[nod] = prev; cnt[nod] = 1;
    deep[nod] = deep[prev] + 1;
    
    int poz = 0;
    for (int i = 0; i < v[nod].size(); i++)
    {
        int x = v[nod][i];
        if (x == prev) continue;
        
        dfs(x, nod);
        cnt[nod] += cnt[x];
        
        if (cnt[x] > cnt[v[nod][poz]]) poz = i;
    }

    if (poz) swap(v[nod][0], v[nod][poz]);
}

int ind = 1;
static void hld(int nod, int prev = 0)
{
    num[nod] = ind++;
    for (int i = 0; i < v[nod].size(); i++)
    {
        int x = v[nod][i];
        if (x == prev) continue;
        
        r[x] = (i == 0 ? r[nod] : x);
        hld(x, nod);
    }
}

static int answ(int x, int y)
{
    int ans = 0;
    for (; r[x] != r[y]; x = p[r[x]])
    {
        if (deep[r[x]] < deep[r[y]]) swap(x, y);
        ans = max(ans, a.maxi(num[r[x]], num[x]));
    }

    if (deep[x] < deep[y]) swap(x, y);

    for (auto z : v[y]) if (z != p[y] && r[z] == r[x]) { y = z; break; }

    ans = max(ans, a.maxi(num[y], num[x]));

    return ans;
}

static int root(int x)
{
    if (t[x] < 0) return x;

    int aux = root(t[x]);
    t[x] = aux;
    return t[x];
}

static void join(int x, int y)
{
    int rx = root(x), ry = root(y);
    if (t[rx] < t[ry]) {
        t[rx] += t[ry];
        t[ry] = rx;
    }

    else {
        t[ry] += t[rx];
        t[rx] = ry;
    }
}

static bool cmp(kr x, kr y) {
    return x.c < y.c;
}

static void Kruskal()
{
    for (int i = 1; i <= n; i++) t[i] = -1;
    sort(e.begin(), e.end(), cmp);

    for (auto b : e)
    {
        int x = b.x, y = b.y, c = b.c;
        if (root(x) != root(y)) {
            join(x, y);
            v2[x].push_back({ y, c });
            v2[y].push_back({ x, c });
        }
    }
}

static void make_tree(int nod, int prev = 0)
{
    bi[nod][0] = prev;
    for (int i = 1; i <= 20; i++)
        bi[nod][i] = bi[bi[nod][i - 1]][i - 1];

    for (auto x : v2[nod])
    {
        if (x.vec == prev) continue;
        
        v[x.vec].push_back(nod);
        v[nod].push_back(x.vec);

        cost[x.vec] = x.c;
        make_tree(x.vec, nod);
    }
}

static int lca(int x, int y)
{
    if (deep[x] < deep[y]) swap(x, y);

    if (deep[x] != deep[y]) {
        int dif = deep[x] - deep[y];
        for (int i = 0; i <= 20; i++)
            if (dif & (1 << i)) x = bi[x][i];
    }

    for (int i = 20; i >= 0; i--)
        if (bi[x][i] != bi[y][i]) 
            x = bi[x][i], y = bi[y][i];
    
    return (x == y ? x : bi[x][0]);
}

int main()
{
    f >> n >> m >> q;
    for (int i = 1; i <= m; i++) {
        int x, y, c;
        f >> x >> y >> c;
        e.push_back({ x, y, c });
    }

    Kruskal(); make_tree(1);

    dfs(1); r[1] = 1; hld(1); a.n = n;

    for (int i = 1; i <= n; i++) a.upd(num[i], cost[i]);

    for (int i = 1; i <= q; i++)
    {
        int x, y; f >> x >> y;
        int l = lca(x, y);
        g << max(answ(x, l), answ(y, l)) << '\n';
    }
    return 0;
}