Cod sursa(job #2503393)

Utilizator FrostfireMagirescu Tudor Frostfire Data 2 decembrie 2019 23:26:15
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#define MMAX 30000
#define NMAX 15000

using namespace std;

ifstream f("radiatie.in");
ofstream g("radiatie.out");

int n, k, m, tata[NMAX+10], rang[NMAX+10], level[NMAX+10];
bool b[NMAX+10];
struct Kruskal
{   int nod1, nod2, cost;
}K[MMAX+10];
pair <int, int> dist[NMAX+10][20];
vector <pair <int, int> > nod[NMAX+10];

inline bool mycmp(Kruskal a, Kruskal b)
{   return a.cost < b.cost;
}

int findSet(int x)
{   int r = x, y = x;
    while(tata[r] != r) r = tata[r];
    while(tata[x] != x)
        {   x = tata[x];
            tata[y] = r;
            y = x;
        }
    return r;
}

void unite(int x, int y)
{   if(rang[x] < rang[y]) tata[x] = y;
    else tata[y] = x;

    if(rang[x] == rang[y]) rang[x]++;
}

void dfs(int x, int tata)
{   level[x] = level[tata] + 1;
    dist[x][0].first = tata;
    b[x] = 1;
    for(int i=0; i<nod[x].size(); i++)
        if(!b[nod[x][i].first])
            {   dist[nod[x][i].first][0].second = nod[x][i].second;
                dfs(nod[x][i].first, x);
            }
}

int lca(int x, int y)
{   if(level[x] < level[y]) swap(x, y);
    int dif = level[x] - level[y], sol = 0;
    for(int i=0; (1<<i)<=dif; i++)
        if(dif & (1 << i))
            {   sol = max(sol, dist[x][i].second);
                x = dist[x][i].first;
            }
    if(x == y) return sol;
    for(int i=15; i>=0; i--)
        {   if(dist[x][i].first && dist[y][i].first && dist[x][i].first != dist[y][i].first)
                {   sol = max(sol, dist[x][i].second);
                    x = dist[x][i].first;
                    sol = max(sol, dist[y][i].second);
                    y = dist[y][i].first;
                }
        }
    return max(sol, max(dist[x][0].second, dist[y][0].second));
}

int main()
{
    f >> n >> m >> k;
    for(int i=1; i<=m; i++) f >> K[i].nod1 >> K[i].nod2 >> K[i].cost;
    sort(K+1, K+m+1, mycmp);
    for(int i=1; i<=n; i++) tata[i] = i;
    for(int i=1; i<=m; i++)
        {   int val1 = findSet(K[i].nod1), val2 = findSet(K[i].nod2);
            if(val1 != val2)
                {   unite(val1, val2);
                    nod[K[i].nod1].push_back(make_pair(K[i].nod2, K[i].cost));
                    nod[K[i].nod2].push_back(make_pair(K[i].nod1, K[i].cost));
                }
        }
    dfs(1, 0);
    for(int i=1; (1<<i)<=n; i++)
        for(int j=1; j<=n; j++)
            {   dist[j][i].first = dist[dist[j][i-1].first][i-1].first;
                dist[j][i].second = max(dist[j][i-1].second, dist[dist[j][i-1].first][i-1].second);
            }
    for(int i=1; i<=k; i++)
        {   int x, y;
            f >> x >> y;
            g << lca(x, y) << '\n';
        }
    return 0;
}