Cod sursa(job #2080759)

Utilizator Coroian_DavidCoroian David Coroian_David Data 3 decembrie 2017 14:59:07
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <bits/stdc++.h>

#define MAX_N 15000
#define MAX_M 30000
#define MAX_LOG 13
#define pb push_back
#define x first
#define y second

using namespace std;

FILE *f;

vector <pair<int, int>> g[MAX_N + 1];

void add(int a, int b, int c)
{
    g[a].pb({b, c});
}

int n, m, q;
int h[MAX_N + 1];
int comp[MAX_N + 1];

struct edg
{
    int a, b, c;
};

edg v[MAX_M + 1];

int tata[MAX_N + 1][MAX_LOG + 1];
int mx[MAX_N + 1][MAX_LOG + 1];

int dep[MAX_N + 1];

void readFile()
{
    f = fopen("radiatie.in", "r");

    fscanf(f, "%d%d%d", &n, &m, &q);

    int i;
    for(i = 1; i <= m; i ++)
        fscanf(f, "%d%d%d", &v[i].a, &v[i].b, &v[i].c);
}

struct cmp
{
    bool operator () (const edg &a, const edg &b) const
    {
        return a.c < b.c;
    }
};

int getComp(int a)
{
    if(comp[a] == a)
        return a;

    return comp[a] = getComp(comp[a]);
}

void uneste(int a, int b)
{
    if(h[a] >= h[b])
    {
        comp[b] = a;
        h[a] += (h[a] == h[b]);
    }

    else
        comp[a] = b;
}

void apm()
{
    sort(v + 1, v + m + 1, cmp());

    int i;
    for(i = 1; i <= n; i ++)
        comp[i] = i;

    for(i = 1; i <= m; i ++)
    {
        int a = v[i].a;
        int b = v[i].b;
        int c = v[i].c;
        int ca = getComp(v[i].a);
        int cb = getComp(v[i].b);

        if(ca != cb)
        {
            uneste(ca, cb);
            add(a, b, c);
            add(b, a, c);
        }
    }
}

int depth;

void dfs(int a, int tat)
{
    dep[a] = (++ depth);

    for(auto u : g[a])
    {
        if(u.x != tat)
        {
            tata[u.x][0] = a;
            mx[u.x][0] = u.y;

            dfs(u.x, a);
        }
    }

    -- depth;
}

void mxs()
{
    int i, j;
    for(j = 1; j <= MAX_LOG; j ++)
    {
        for(i = 1; i <= n; i ++)
        {
            if(tata[i][j - 1] != 0)
            {
                tata[i][j] = tata[tata[i][j - 1]][j - 1];
                mx[i][j] = max(mx[i][j - 1], mx[tata[i][j - 1]][j - 1]);
            }
        }
    }
}

void solve()
{
    apm();

    dfs(1, 0);

    mxs();
}

int getRez(int a, int b)
{
    if(dep[a] < dep[b])
        swap(a, b);

    //cout << a << " + " << b << " " << dep[a] << " " << dep[b] << "\n";

    int rez = 0;
    int diff = dep[a] - dep[b];
    for(int pas = 0; pas <= MAX_LOG; pas ++)
    {
        if(((1 << pas) & diff) != 0)
        {
            rez = max(rez, mx[a][pas]);
            a = tata[a][pas];
        }
    }

    if(a == b)
        return rez;

    for(int pas = MAX_LOG; pas >= 0; pas --)
    {
        if(tata[a][pas] != 0 && tata[b][pas] != 0)
        if(tata[a][pas] != tata[b][pas])
        {
            rez = max(rez, mx[a][pas]);
            rez = max(rez, mx[b][pas]);

            a = tata[a][pas];
            b = tata[b][pas];
        }
    }

    rez = max(rez, mx[a][0]);
    rez = max(rez, mx[b][0]);

    return rez;
}

void ansQues()
{
    FILE *g = fopen("radiatie.out", "w");

    while(q > 0)
    {
        int a, b;
        fscanf(f, "%d%d", &a, &b);

        fprintf(g, "%d\n", getRez(a, b));

        q --;
    }

    fclose(f);
    fclose(g);
}

int main()
{
    readFile();

    solve();

    ansQues();

    return 0;
}