Cod sursa(job #3304625)

Utilizator AndreiNicolaescuEric Paturan AndreiNicolaescu Data 25 iulie 2025 16:39:59
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.11 kb
#include <bits/stdc++.h>
#define cin ci
#define cout co
using namespace std;
ifstream cin("radiatie.in");
ofstream cout("radiatie.out");
const int Nmax = 15e3 + 1;
const int Lmax = 21;
int n, m, k, x, y, z;
int anc[Nmax][Lmax], dist[Nmax], val[Nmax][Lmax];
vector<vector<pair<int, int>>> graf, graff;
struct edge
{
    int x, y, c;
    friend bool operator <(edge &a, edge &b)
    {
        return a.c < b.c;
    }
};
vector<edge> edges;
vector<int> parent, rang;
int findroot(int node)
{
    if(node == parent[node])
        return node;
    parent[node] = findroot(parent[node]);
    return parent[node];
}
void unionset(int node1, int node2)
{
    node1 = findroot(node1);
    node2 = findroot(node2);
    if(node1 == node2)
        return;
    if(rang[node1] < rang[node2])
        swap(node1, node2);
    if(rang[node1] == rang[node2])
        rang[node1]++;
    parent[node2] = node1;
}
void dfs(int node, int par)
{
    anc[node][0] = par;
    dist[node] = dist[par] + 1;
    for(auto &[next, cost]:graff[node])
        if(next != par)
        {
            val[next][0] = cost;
            dfs(next, node);
        }
}
void binary()
{
    for(int l=1; l<Lmax; l++)
        for(int node=1; node <= n; node++)
        {
            anc[node][l] = anc[anc[node][l - 1]][l - 1];
            val[node][l] = max(val[node][l - 1], val[anc[node][l - 1]][l - 1]);
        }

}
pair<int, int> findanc(int node, int nanc)
{
    int ans = 0;
    for(int l=0; l<Lmax; l++)
        if(nanc & (1 << l))
        {
            ans = max(ans, val[node][l]);
            node = anc[node][l];
        }

    return {node, ans};
}
int lca(int node1, int node2)
{
    int ans = 0;
    if(dist[node1] < dist[node2])
        swap(node1, node2);
    pair<int, int> aux = findanc(node1, dist[node1] - dist[node2]);
    node1 = aux.first;
    ans = aux.second;
    if(node1 == node2)
        return ans;

    for(int l=Lmax -1; l>=0; l--)
        if(anc[node1][l] != anc[node2][l])
        {
            ans = max({ans, val[node1][l], val[node2][l]});
            node1 = anc[node1][l];
            node2 = anc[node2][l];
        }
    return max({ans, val[node1][0], val[node2][0]});
}
int main()
{
    cin >> n >> m >> k;
    graf.assign(n + 1, vector<pair<int, int>>());
    parent.resize(n+1);
    rang.resize(n+1);
    for(int i=1; i<=n; i++)
    {
        parent[i] = i;
        rang[i] = 1;
    }
    for(int i=1; i<=m; i++)
    {
        cin >> x >> y >> z;
        graf[x].push_back({y, z});
        graf[y].push_back({x, z});
        edges.push_back({x, y, z});
    }
    sort(edges.begin(), edges.end());
    graff.assign(n+1, vector<pair<int, int>>());
    for(int i=0; i<m; i++)
        if(findroot(edges[i].x) != findroot(edges[i].y))
        {
            unionset(edges[i].x, edges[i].y);
            graff[edges[i].x].push_back({edges[i].y, edges[i].c});
            graff[edges[i].y].push_back({edges[i].x, edges[i].c});
        }
    dfs(1, 0);
    binary();
    while(k--)
    {
        cin >> x >> y;
        cout << lca(x, y) << '\n';
    }
    return 0;
}