Cod sursa(job #3279169)

Utilizator NonnonsniperCretu Marian-Dumitru Nonnonsniper Data 21 februarie 2025 23:10:10
Problema Radiatie Scor 10
Compilator cpp-64 Status done
Runda lasm_21_02_2025_clasa11 Marime 3.02 kb
#include <bits/stdc++.h>

using namespace std;

const int N_MAX = 15001, LOG_N = 12, M_MAX = 30001, K_MAX = 15001;
int N, M, K, logN;

int timer;
int tin[N_MAX], tout[N_MAX];
int T[N_MAX][LOG_N];
int Max[N_MAX][LOG_N];

struct Edge
{
    int v1, v2, c;

    inline bool operator< (const Edge& rhs) const
    {
        return c < rhs.c;
    }
};

Edge G[M_MAX];
vector<int> Ad[N_MAX];

struct DisjointSetUnion
{
    int T[N_MAX];
    int Size[N_MAX];
    int N;

    inline void MakeSet(int v)
    {
        T[v] = v;
        Size[v] = 1;
    }

    int FindSet(int v)
    {
        if(T[v] != v)
            T[v] = FindSet(T[v]);
        return T[v];
    }

    bool AreDisjointed(int a, int b)
    {
        return FindSet(a) != FindSet(b);
    }

    void TryUnion(int a, int b, int c)
    {
        a = FindSet(a);
        b = FindSet(b);

        if(a == b)
            return;

        if(Size[a] < Size[b])
            swap(a, b);

        T[b] = a;
        Max[b][0] = c;
        Ad[a].push_back(b);

        Size[a] += Size[b];
    }

    void Build(int N)
    {
        this->N = N;

        for(int i = 1; i <= N; i++)
            MakeSet(i);
    }
} dsu;

void SetInput(string name)
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    (void)!freopen((name + ".in").c_str(), "r", stdin);
    (void)!freopen((name + ".out").c_str(), "w", stdout);
}

void ReadInput()
{
    cin >> N >> M >> K;
    for(int i = 0; i < M; i++)
        cin >> G[i].v1 >> G[i].v2 >> G[i].c;
}

bool IsAncestor(int u, int v)
{
    return tin[u] <= tin[v] && tout[u] >= tout[v];
}

void DFS(int v, int p)
{
    tin[v] = ++timer;

    T[v][0] = p;
    for(int i = 1; i <= logN; i++)
    {
        T[v][i] = T[T[v][i-1]][i-1];
        Max[v][i] = max(Max[v][i-1], Max[T[v][i-1]][i-1]);
    }

    for(int& u : Ad[v])
        DFS(u, v);

    tout[v] = ++timer;
}

int LCA(int u, int v)
{
    if(IsAncestor(u, v))
        return u;

    if(IsAncestor(v, u))
        return v;

    for(int i = logN; i >= 0; i--)
        if(not IsAncestor(T[u][i], v))
            u = T[u][i];

    return T[u][0];
}

int FindMaxInPath(int v, int p)
{
    int ans = 0;
    for(int i = logN; i >= 0; i--)
        if(not IsAncestor(T[v][i], p))
        {
            ans = max(ans, Max[v][i]);
            v = T[v][i];
        }

    ans = max(ans, Max[v][0]);

    return ans;
}

void Solve()
{
    sort(G, G + M);

    /// Kruskal

    for(int i = 0; i < M; i++)
        dsu.TryUnion(G[i].v1, G[i].v2, G[i].c);

    logN = ceil(log2(N));
    int root = dsu.T[1];
    Max[root][0] = 0;
    DFS(root, root);

    for(int i = 0, u, v, lca, ans; i < K; i++)
    {
        cin >> u >> v;
        lca = LCA(u, v);

        ans = FindMaxInPath(u, lca);
        ans = max(ans, FindMaxInPath(v, lca));
        cout << ans << '\n';
    }
}

int main()
{
    SetInput("radiatie");

    ReadInput();
    dsu.Build(N);
    Solve();

    return 0;
}