Cod sursa(job #1957834)

Utilizator alittlezzCazaciuc Valentin alittlezz Data 7 aprilie 2017 20:02:03
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.99 kb
#include <bits/stdc++.h>

using namespace std;

const int N = 15005;
const int lgN = 15;
vector < int > v[N];
vector < pair < int, int > > Q[N];
int normalized[N];
int root[N], fs[N], sn[N], ans[N], euler[2*N], aint[8*N], dfsV[N], cost[N], lg2[N];
int dp[N];
int rmq[N][lgN];
int qlf, qrg, all;
const int INF = 1<<30;

struct thing{
    int x, y, c;
}edge[2 * N];

bool comp(thing a, thing b){
    return a.c < b.c;
}

int getRoot(int x){
    if(root[x] != x){
        return root[x] = getRoot(root[x]);
    }
    return root[x];
}

void unite(int x, int y){
    x = getRoot(x);
    y = getRoot(y);
    root[y] = x;
}

void eulerTour(int node, int parent){
    int rn = normalized[node];
    euler[++all] = rn;
    fs[rn] = all;
    for(auto it : v[node]){
        if(it != parent){
            eulerTour(it, node);
            euler[++all] = rn;
        }
    }
    sn[rn] = all;
}

void build(int pos, int lf, int rg){
    if(lf == rg){
        aint[pos] = euler[lf];
        return;
    }
    int md = (lf + rg)/2;
    build(2 * pos, lf, md);
    build(2 * pos + 1, md + 1, rg);
    aint[pos] = min(aint[2 * pos], aint[2 * pos + 1]);
}

int query(int pos, int lf, int rg){
    if(lf > qrg || rg < qlf){
        return INF;
    }
    if(qlf <= lf && rg <= qrg){
        return aint[pos];
    }
    int md = (lf + rg)/2;
    return min( query(2 * pos, lf, md), query(2 * pos + 1, md + 1, rg) );
}

int getMax(int x, int y){
    if(x < y){
        return -INF;
    }
    int lg = lg2[x - y + 1];
    return max(rmq[dfsV[x]][lg], rmq[dfsV[y + (1<<lg) - 1]][lg]);
}

void dfs(int node, int parent, int depth){
    int rn = normalized[node];
    dfsV[depth] = rn;
    dp[rn] = depth;
    rmq[rn][0] = cost[node];
    for(int j = 1;(1<<j) <= depth;j++){
        rmq[rn][j] = max(rmq[rn][j - 1], rmq[dfsV[depth - (1<<(j - 1))]][j - 1]);
    }
    for(auto it : Q[rn]){
        ans[it.second] = max(ans[it.second], getMax(dp[rn], dp[it.first] + 1));
    }
    for(auto it : v[node]){
        if(it != parent){
            dfs(it, node, depth + 1);
        }
    }
}

int cnt;
bool used[2*N];
int p[N];

void liniarize(int node, int parent){
    cnt++;
    p[node] = parent;
    normalized[node] = cnt;
    for(auto it : v[node]){
        if(it != parent){
            liniarize(it, node);
        }
    }
}

int main(){
    int n,m,q,i,j;
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    scanf("%d %d %d", &n, &m, &q);
    for(i = 1;i <= n;i++){
        root[i] = i;
        for(j = 1;j < lgN;j++){
            rmq[i][j] = -INF;
        }
    }
    lg2[2] = 1;
    for(i = 3;i <= N;i++){
        lg2[i] = lg2[i >> 1] + 1;
    }
    for(i = 1;i <= m;i++){
        int x, y, c;
        scanf("%d %d %d", &x, &y, &c);
        edge[i] = {x, y, c};
    }
    sort(edge + 1, edge + m + 1, comp);
    cost[1] = -INF;
    for(i = 1;i <= m;i++){
        int x, y;
        x = edge[i].x;
        y = edge[i].y;
        if(getRoot(x) != getRoot(y)){
            v[x].push_back(y);
            v[y].push_back(x);
            used[i] = 1;
            unite(x, y);
        }
    }
    liniarize(1, 0);
    for(i = 1;i <= m;i++){
        if(used[i]){
            int x, y;
            x = edge[i].x;
            y = edge[i].y;
            if(p[y] == x){
                cost[y] = edge[i].c;
            }else{
                cost[x] = edge[i].c;
            }
        }
    }
    eulerTour(1, 0);
    build(1, 1, all);
    for(i = 1;i <= q;i++){
        ans[i] = -INF;
        int x, y;
        scanf("%d %d", &x, &y);
        x = normalized[x];
        y = normalized[y];
        if(fs[x] > sn[y]){
            swap(x, y);
        }
        qlf = fs[x];
        qrg = sn[y];
        int LCA = query(1, 1, all);
        Q[x].push_back({LCA, i});
        Q[y].push_back({LCA, i});
    }
    dfs(1, 0, 1);
    for(i = 1;i <= q;i++){
        printf("%d\n", ans[i]);
    }
    return 0;
}