Cod sursa(job #1893547)

Utilizator marcdariaDaria Marc marcdaria Data 25 februarie 2017 19:21:10
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>

using namespace std;

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

struct edges
{
    int a, b, c;
} v[30010];

bool apm[30010];
int n, m, k;
vector<int> g[15010];
int level[15010];
bool viz[15010];


bool cmp(edges x, edges y)
{
    return x.c < y.c;
}

int p[15010];
struct
{
    int nod, val;
} rmq[20][15010];

void init()
{
    for(int i = 1; i <= n; i++)
        p[i] = i;
}

int find(int x)
{
    int ans = x;
    while(p[ans] != ans)
        ans = p[ans];
    while(p[x] != ans)
    {
        int tmp = p[x];
        p[x] = ans;
        x = tmp;
    }
    return ans;
}

void join(int x, int y)
{
    x = find(x);
    y = find(y);
    p[x] = y;
}

void dfs(int nod, int last)
{
    level[nod] = level[last] + 1;
    viz[nod] = 1;
    for(int i = 0; i < g[nod].size(); i++)
        if(viz[g[nod][i]] == 0)
            dfs(g[nod][i], nod);

}

int lca(int a, int b)
{
    int x = level[a], y = level[b];
    int diff = x - y, res = 0;

    ///climb

    if(diff > 0)
    {
        int p = 14, nivel = diff;
        while(p >= 0)
        {
            if((1 << p) <= nivel)
            {
                res = max(res, rmq[p][a].val);
                a = rmq[p][a].nod;
                nivel -= (1 << p);
            }
            p--;
        }
    }
    else
    {
        int p = 14, nivel = -diff;
        while(p >= 0)
        {
            if((1 << p) <= nivel)
            {
                res = max(res, rmq[p][b].val);
                b = rmq[p][b].nod;
                nivel -= (1 << p);
            }
            p--;
        }
    }


    if(a == b)
        return res;

    int p = 14;
    while(p >= 0 && rmq[p][a].nod == rmq[p][b].nod)
    {
        p--;
        if(p >= 0 && rmq[p][a].nod != rmq[p][b].nod)
        {
            res = max(res, max(rmq[p][a].val, rmq[p][b].val));
            a = rmq[p][a].nod;
            b = rmq[p][b].nod;
        }
    }
    res = max(max(rmq[0][a].val, rmq[0][b].val), res);

    return res;
}

int main()
{

    fin>>n>>m>>k;

    for(int i = 1; i <= m; i++)
        fin>>v[i].a>>v[i].b>>v[i].c;

    sort(v + 1, v + m + 1, cmp);

    init();

    for(int i = 1; i <= m; i++)
    {
        int x = v[i].a, y = v[i].b;
        if(find(x) != find(y))
        {
            join(x, y);
            g[x].push_back(y);
            g[y].push_back(x);
            apm[i] = 1;
        }
    }
    dfs(1, 0);

    for(int i = 1; i <= m; i++)
    {
        if(apm[i] == 1)
        {
            int x = v[i].a, y = v[i].b;
            if(level[x] < level[y])
            {
                rmq[0][y].nod = x;
                rmq[0][y].val = v[i].c;
            }
            else
            {
                rmq[0][x].nod = y;
                rmq[0][x].val = v[i].c;
            }
        }
    }

    ///stramosi

    for(int i = 1; i <= 14; i++)
        for(int j = 1; j <= n; j++)
        {
            rmq[i][j].nod = rmq[i - 1][rmq[i - 1][j].nod].nod;
            rmq[i][j].val = max(rmq[i - 1][j].val, rmq[i - 1][rmq[i - 1][j].nod].val);
        }

    for(int i = 1; i <= k; i++)
    {
        int a, b;
        fin>>a>>b;
        fout<<lca(a, b)<<'\n';
    }


    return 0;
}