Cod sursa(job #3217357)

Utilizator solicasolica solica solica Data 22 martie 2024 14:05:03
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

#define NMAX 15008
#define LOG 15
#define pii pair<int,int>

struct muchie
{
    int x,y,cost;
};

int n,i,j,q,dsu[NMAX],a,b,cost,m,depth[NMAX];

pii parent[LOG][NMAX];

vector<muchie>muchii;

vector<pii>edges[NMAX];

void input();

int set_find(int node);

void set_unite(int node1, int node2);

bool crt (muchie a, muchie b);

void precalc_lca();

void dfs(int node, int ad, int parinte, int cost);

int lca (int u, int v);

int main()
{
    input();
    for (i=1; i<=n; i++)
    {
        dsu[i]=i;
    }
    sort(muchii.begin(),muchii.end(),crt);
    for (i=0; i<m; i++)
    {
        a=muchii[i].x,b=muchii[i].y,cost=muchii[i].cost;
        if (set_find(a)!=set_find(b))
        {
            edges[a].push_back({b,cost});
            edges[b].push_back({a,cost});
            set_unite(a,b);
        }
    }
    dfs(1,1,1,0);
    precalc_lca();
    while (q--)
    {
        fin>>a>>b;
        fout<<lca(a,b)<<'\n';
    }
    return 0;
}

int lca (int u, int v)
{
    int answer=0;
    if (depth[u]<depth[v])
    {
        swap(u,v);
    }
    for (i=LOG-1; i>=0; i--)
    {
        if (depth[u]-(1<<i)>=depth[v])
        {
            answer=max(answer,parent[i][u].second);
            u=parent[i][u].first;
        }
    }
    if (u==v)
    {
        return answer;
    }
    for (i=LOG-1; i>=0; i--)
    {
        if (parent[i][u].first && parent[i][u].first!=parent[i][v].first)
        {
            answer=max(answer,max(parent[i][u].second,parent[i][v].second));
            u=parent[i][u].first,v=parent[i][v].first;
        }
    }
    answer=max(answer,parent[0][u].second);
    answer=max(answer,parent[0][v].second);
    return answer;
}

void precalc_lca()
{
    for (i=1; i<LOG; i++)
    {
        for (j=1; j<=n; j++)
        {
            if (parent[i-1][j].first)
            {
                parent[i][j].first=parent[i-1][parent[i-1][j].first].first;
                parent[i][j].second=max(parent[i-1][j].second,parent[i-1][parent[i-1][j].first].second);
            }
        }
    }
}

void dfs(int node, int ad, int parinte, int cost)
{
    depth[node]=ad;
    parent[0][node]={parinte,cost};
    for (auto vec : edges[node])
    {
        if (vec.first!=parinte)
        {
            dfs(vec.first,ad+1,node,vec.second);
        }
    }
}

bool crt(muchie a, muchie b)
{
    return a.cost<b.cost;
}

void set_unite(int node1, int node2)
{
    dsu[set_find(node1)]=set_find(node2);
}

int set_find(int node)
{
    if (node==dsu[node])
    {
        return node;
    }
    return dsu[node]=set_find(dsu[node]);
}

void input()
{
    fin>>n>>m>>q;
    for (i=1; i<=m; i++)
    {
        fin>>a>>b>>cost;
        muchii.push_back({a,b,cost});
    }
}