Cod sursa(job #974869)

Utilizator crisbodnarCristian Bodnar crisbodnar Data 18 iulie 2013 16:24:58
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.29 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

#define aa second.second.first
#define bb second.second.second
#define newn a[x][i].second
#define cost a[x][i].first

using namespace std;

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

const int N = 15010;
const int E = 2 * N;
const int L = 15;
const int M = 30010;

int n, m, k, nr, s, c[N], lg[E], dt[N], first[N],
h[E], euler[E], rmq[L][E], t[L][N], dp[L][N];
typedef pair <int, int> muchie;
typedef pair <int, muchie> muchie2;
typedef pair <int, muchie2> arb;
vector <arb> graf;
vector <muchie> a[N];
vector <int> mc[N];
vector <bool> viz(N), uz(M);

int tata(int x)
{
    if(x != c[x]) c[x] = tata(c[x]);
    return c[x];
}

void Apm()
{
    int nrm = 0;
    for(int i=1; i<=n; i++) c[i] = i;
    sort(graf.begin(), graf.end());

    for(int i = 0; nrm <= n-1 && i < m; i++)
    {
        int x = tata(graf[i].aa), y = tata(graf[i].bb);
        if(x != y)
        {
            uz[graf[i].second.first] = 1;
            s = graf[i].aa;
            c[x] = y;
            nrm++;
        }
    }
}

void dfs(int x, int level)
{
    viz[x] = 1;
    h[++nr] = level;
    euler[nr] = x;
    first[x] = nr;
    for(unsigned i=0; i<a[x].size(); i++)
        if(!viz[newn] && uz[mc[x][i]])
        {
            dfs(newn, level+1);
            h[++nr] = level;
            euler[nr] = x;
            c[newn] = x;
            dt[newn] = cost;
        }
}

void Rmq()
{
    for(int i=2; i<=nr; i++)
        lg[i] = lg[i>>1] + 1;
    for(int i=1; i<=nr; i++)
        rmq[0][i] = i;

    for(int i=1; (1<<i) <= nr; i++)
        for(int j=1; j <= nr - (1<<i); j++)
        {
            const int l = 1 << (i -1);
            rmq[i][j] = rmq[i-1][j];
            if(h[rmq[i][j]] > h[rmq[i-1][j+l]])
                rmq[i][j] = rmq[i-1][j+l];
        }
}

void Ancestor()
{
    for(int i=1; i<=n; i++)
        t[0][i] = c[i], dp[0][i] = dt[i];
    for(int i=1; (1<<i) <= n; i++)
        for(int j=1; j<=n; j++)
        {
            t[i][j] = t[i-1][t[i-1][j]];
            dp[i][j] = max(dp[i-1][j], dp[i-1][t[i-1][j]]);
        }
}

int LCA(int x, int y)
{
    x = first[x], y = first[y];
    if(x > y) swap(x, y);

    const int l = lg[y-x+1];
    int poz = rmq[l][x];
    if(h[poz] > h[rmq[l][y-(1<<l)+1]])
        poz = rmq[l][y-(1<<l)+1];
    return euler[poz];
}

int Compute(int nod, int lca)
{
    int rez = 0, depth = h[first[nod]] - h[first[lca]];

    while(depth)
    {
        rez = max(rez, dp[lg[depth]][nod]);
        nod = t[lg[depth]][nod];
        depth -= (1 << lg[depth]);
    }
    return rez;
}

void Query(int x, int y)
{
    int lca = LCA(x, y);
    int drum1 = Compute(x, lca);
    int drum2 = Compute(y, lca);
    fout<<max(drum1, drum2)<<'\n';
}

int main()
{
    fin>>n>>m>>k;
    for(int i=1; i<=m ;i++)
    {
        int x, y, c;
        fin>>x>>y>>c;
        mc[x].push_back(i);
        mc[y].push_back(i);
        a[x].push_back(muchie(c, y));
        a[y].push_back(muchie(c, x));
        graf.push_back(arb(c, muchie2(i, muchie(x, y))));
    }

    Apm(); dfs(s, 1); Rmq(); Ancestor();
    while(k--)
    {
        int x, y;
        fin>>x>>y;
        Query(x, y);
    }
    return 0;
}