Cod sursa(job #3224588)

Utilizator AndreasBossGamerBaragau Andreas AndreasBossGamer Data 15 aprilie 2024 18:07:42
Problema Radiatie Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.44 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

struct muchie
{
    int node1, node2, cost;

    bool operator<(const muchie& temp) const
    {
        return cost < temp.cost;
    }
};

struct ceva
{
    int node, cost;
};

int n, m, q;
    
vector<vector<ceva>> adj;
vector<int> parent;
vector<int> rang;
int root(int x)
{
    int repX;
    for (repX = x; repX != parent[repX]; repX = parent[repX]);
    return repX;
}

void unire(int x, int y)
{
    int repX = root(x);
    int repY = root(y);

    if (repX == repY) return;

    if (rang[repX] > rang[repY]) parent[repY] = repX;
    else if (rang[repY] > rang[repX]) parent[repX] = repY;
    else
    {
        rang[repX]++;
        parent[repY] = repX;
    }
}

vector<int> depth;
int rmq[15][15001];
int ancest[15][15001];
void dfs(int node, int parent)
{
    for (auto pula : adj[node])
    {
        int vecin = pula.node;
        int cost = pula.cost;
        if (vecin == parent) continue;

        depth[vecin] = depth[node] + 1;
        rmq[0][vecin] = cost;
        ancest[0][vecin] = node;

        for (int e = 1; e <= 14; e++)
        {
            if (ancest[e - 1][vecin] == 0)
                break;

            ancest[e][vecin] = ancest[e - 1][ancest[e - 1][vecin]];
            rmq[e][vecin] = max(rmq[e - 1][vecin], rmq[e - 1][ancest[e-1][vecin]]);
        }

        dfs(vecin, node);
    }
}

void query(int node1, int node2)
{
    int maxUntilNow = 0;
    //egalizare
    if (depth[node1] != depth[node2])
    {
        //vreau ca node1 sa fie mai jos pt simplitate
        if (depth[node1] < depth[node2])
            swap(node1, node2);

        int dif = depth[node1] - depth[node2];
        for (int e = 0; e <= 14; e++)
        {
            if (dif & (1 << e))
            {
                maxUntilNow = max(maxUntilNow, rmq[e][node1]);
                node1 = ancest[e][node1]; 
            }
        }
    }

    if (node1 == node2) cout << maxUntilNow << '\n';
    else
    {
        //binary lifting
        for (int e = 14; e >= 0; e--)
        {
            if (ancest[e][node1] != ancest[e][node2])
            {
                maxUntilNow = max(maxUntilNow, max(rmq[e][node1], rmq[e][node2]));
                node1 = ancest[e][node1];
                node2 = ancest[e][node2];
            }
        }
        cout << maxUntilNow << '\n';
    }
    
}

int main()
{
    cin >> n >> m >> q;
    vector<muchie> muc;
    muc.resize(m + 1);
    for (int i = 1; i <= m; i++)
    {
        int x, y, cost;
        cin >> x >> y >> cost;
        muc[i] = { x, y, cost };
    }

    sort(muc.begin() + 1, muc.begin() + m + 1);
    parent.resize(m + 1), rang.resize(m + 1);
    for (int i = 1; i <= m; i++)
    {
        parent[i] = i;
        rang[i] = 1;
    }


    adj.resize(n + 1);
    for (int i = 1; i <= m; i++)
    {
        int node1 = muc[i].node1;
        int node2 = muc[i].node2;
        int cost = muc[i].cost;

        if (root(node1) != root(node2))
        {
            adj[node1].push_back({ node2, cost });
            adj[node2].push_back({ node1, cost });
            unire(node1, node2);
        }
    }

    depth.resize(n + 1);
    dfs(1, -1);

    for (int i = 1; i <= q; i++)
    {
        int x, y;
        cin >> x >> y;
        query(x, y);
    }
}