Cod sursa(job #3155318)

Utilizator Luka77Anastase Luca George Luka77 Data 7 octombrie 2023 20:51:59
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.5 kb
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define FOR(n) for(int i = 1; i <= n; ++ i)
using namespace std;

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

/// STRUCTURES
struct edge
{
    int x, y, cost;

    edge()
    {
        x = -1;
        y = -1;
        cost = INT_MAX;
    }

    edge(int _x, int _y, int _cost)
    {
        x = _x;
        y = _y;
        cost = _cost;
    }
};

struct DSU
{
    vector<int>father, sz, fat_c;

    DSU(int n)
    {
        father.resize(n + 1);
        sz.resize(n + 1);
        fat_c.resize(n + 1);

        for(int i = 1; i <= n; ++ i)
        {
            father[i] = i;
            sz[i] = 1; 
            fat_c[i] = 0;
        }
    }

    inline int Find_Father(int x)
    {
        while(father[x] != x)
            x = father[x];
            
        return x;
    }

    inline bool Same_Father(int x, int y)
    {
        return Find_Father(x) == Find_Father(y);
    }

    inline void Join(int x, int y, int cost)
    {
        int father_x = Find_Father(x), father_y = Find_Father(y);

        if(father_x == father_y)
            return;

        if(sz[father_x] > sz[father_y])
            swap(father_x, father_y);

        sz[father_y] += sz[father_x];
        father[father_x] = father_y;
        fat_c[father_x] = cost;
    }
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// GLOBAL VARIABLES
const int NMAX = 15005;
int nodes, edges, queries;
bool viz[NMAX];
int depth[NMAX];
vector<int>adj[NMAX];
vector<edge>graph;
DSU apm(NMAX);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

inline bool custom_sort(const edge &x, const edge &y)
{
    return x.cost < y.cost;
}

inline void DFS(int curr_node, int h)
{
    if(viz[curr_node])
        return;
    viz[curr_node] = 1;
    depth[curr_node] = h;

    for(auto new_node : adj[curr_node])
        DFS(new_node, h + 1);
}

int main()
{
    ios::sync_with_stdio(false);
    fin.tie(NULL);
    fout.tie(NULL);

    fin >> nodes >> edges >> queries;

    for(int i = 1; i <= edges; ++ i)
    {
        int x, y, cost;
        fin >> x >> y >> cost;
        graph.push_back({x, y, cost});
    }

    sort(graph.begin(), graph.end(), custom_sort);

    for(int i = 0; i < graph.size(); ++ i)
    {
        if(!apm.Same_Father(graph[i].x, graph[i].y))
        {
            int father_x = apm.Find_Father(graph[i].x), father_y = apm.Find_Father(graph[i].y);
            adj[father_x].push_back(father_y);
            adj[father_y].push_back(father_x);
            apm.Join(graph[i].x, graph[i].y, graph[i].cost);
        }
    }

    int root = apm.Find_Father(1);

    DFS(root, 0);

    for(int i = 1; i <= queries; ++ i)
    {
        int ans = 0;
        int a, b;
        fin >> a >> b;

        while(depth[a] > depth[b])
        {
            ans = max(ans, apm.fat_c[a]);
            a = apm.father[a];
        }

        while(depth[a] < depth[b])
        {
            ans = max(ans, apm.fat_c[b]);
            b = apm.father[b];
        }

        while(a != b)
        {
            ans = max(ans, apm.fat_c[a]);
            a = apm.father[a];
            ans = max(ans, apm.fat_c[b]);
            b = apm.father[b];
        }
        fout << ans << '\n';
    }
}