Cod sursa(job #2864792)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 8 martie 2022 11:14:59
Problema Radiatie Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.58 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

ifstream fin("radiatie.in");
ofstream fout("radiatie.out");

struct Edge
{
    int a, b;
    int c;
};

struct Node
{
    int destination;
    int cost;
};

bool cmp(const Edge& a, const Edge& b)
{
    return a.c < b.c;
}

int n, m, k;
vector <Edge> edges;
vector <Node> graph[15005];
int fathers[15005];
int level[100005];
Node ancestors[20][100005];
bool visited[15005];
int logE;


int FindRoot(int node)
{
    if (node == fathers[node])
    {
        return node;
    }
    return fathers[node] = FindRoot(fathers[node]);
}

void Union(int a, int b)
{
    a = FindRoot(a);
    b = FindRoot(b);

    if (rand() % 2 == 1)
    {
        fathers[b] = a;
    }
    else
    {
        fathers[a] = b;
    }
}

int LCA(int a, int b)
{
    if (a == b)
    {
        return 0;
    }
    int maxVal = 0;

    for (int e = logE; e >= 0; e--)
    {
        maxVal = max(maxVal, ancestors[e][a].cost);
        maxVal = max(maxVal, ancestors[e][b].cost);
        if (ancestors[e][a].destination != ancestors[e][b].destination)
        {
            a = ancestors[e][a].destination;
            b = ancestors[e][b].destination;
        }
    }
    return maxVal;
}

int Equalize(int &a, int &b)
{
    int e = logE;
    int maxVal = 0;
    while (level[b] - level[a] > 0)
    {
        //maxVal = max(maxVal, ancestors[e][a].cost);
        
        int dif = level[b] - level[a];
        if ((1 << e) <= dif)
        {
            maxVal = max(maxVal, ancestors[e][b].cost);
            b = ancestors[e][b].destination;
        }
        e--;
    }
    
    return maxVal;
}

int DFS(int node, int lvl)
{
    visited[node] = true;
    level[node] = lvl;
    int currMax = lvl;
    //cout << node << ' ';
    for (Node x : graph[node])
    {
        if (visited[x.destination])
        {
            continue;
        }
        currMax = max(DFS(x.destination, lvl + 1), currMax);
        ancestors[0][x.destination] = {node, x.cost};
        fathers[x.destination] = node;
    }
    return currMax;
}

int main()
{
    fin >> n >> m >> k;
    for (int i = 0; i < m; i++)
    {
        int a, b, c;
        fin >> a >> b >> c;
        Edge newEdge = {a, b, c};
        edges.push_back(newEdge);
    }
    sort(edges.begin(), edges.end(), cmp);
    
    for (int i = 1; i <= n; i++)
    {
        fathers[i] = i;
    }

    for (Edge edge : edges)
    {
        if (FindRoot(edge.a) == FindRoot(edge.b))
        {
            continue;
        }
        //cout << edge.c << ' ';
        Union(edge.a, edge.b);
        Node newNode = {edge.b, edge.c};

        graph[edge.a].push_back(newNode);

        newNode = {edge.a, edge.c};

        graph[edge.b].push_back(newNode);
    }

    logE = (int)log2(DFS(1, 1));
    for (int e = 1; e <= logE; e++)
    {
        for (int i = 1; i <= n; i++)
        {
            ancestors[e][i].destination = ancestors[e - 1][ancestors[e - 1][i].destination].destination;
            ancestors[e][i].cost = max(ancestors[e - 1][i].cost, ancestors[e - 1][ancestors[e - 1][i].destination].cost);
            
        }
    }

    for (int i = 0; i < k; i++)
    {
        int a, b;
        fin >> a >> b;
        int maxVal;
        if (level[a] > level[b])
        {
            maxVal = Equalize(b, a);
        }
        else
        {
            maxVal = Equalize(a, b);
        }

        fout << max(maxVal, LCA(a, b)) << '\n';
    }

}