Cod sursa(job #2446170)

Utilizator CharacterMeCharacter Me CharacterMe Data 7 august 2019 13:16:54
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.42 kb
#include <bits/stdc++.h>
#define tiii tuple<int, int, int>
#define pii pair<int, int>
#define mt make_tuple
#define mp make_pair
#define cost first
#define node second
#define maxa int(log2(15001)+2)
#define maxl int(log2(30001)+2)
#define inf 2147483647
using namespace std;
int n, m, k, i, j, v;
int up[15001], dad[15001], level[15001], first[15001], ancest[maxa][15001], maximum[maxa][15001], rmq[maxl][30001];
vector<pii> graph[15001];
vector<int> tree[15001];
bool inmcst[15001];
priority_queue<tiii, vector<tiii>, greater<tiii> > pq;

void read();
void prep();
void write();
void formcst(int total);
void formanc(int node);
void formlca(int node);
int mn(int node1, int node2);
int main()
{
    read();
    prep();
    write();
    return 0;
}
void read(){
    freopen("radiatie.in", "r", stdin);
    scanf("%d%d%d", &n, &m, &k);
    for(i=1; i<=m; ++i){
        int x, y, c;
        scanf("%d%d%d", &x, &y, &c);
        graph[x].push_back(mp(c, y));
        graph[y].push_back(mp(c, x));
    }
    return;
}
void prep(){
    pq.push(mt(0, 0, 1));
    formcst(n);
    level[0]=-1;
    formanc(1);
    formlca(1);
    for(j=1; (1<<j)<=v; ++j){
        for(i=1; i<=v; ++i){
            rmq[j][i]=rmq[j-1][i];
            int next=i+(1<<(j-1));
            if(next<=v) rmq[j][i]=mn(rmq[j][i], rmq[j-1][next]);
        }
    }
    return;
}
void write(){
    freopen("radiatie.out", "w", stdout);
    for(i=1; i<=k; ++i){
        int x, y, out=0;
        scanf("%d%d", &x, &y);
        int fx=first[x], fy=first[y];
        if(fx>fy){swap(fx, fy); swap(x, y);}
        int soli, j=int(log2(fy-fx+1));
        soli=mn(rmq[j][fx], rmq[j][fy-(1<<j)+1]);
        int p1=level[x]-level[soli], p2=level[y]-level[soli];
        while(p1){
            j=int(log2(p1));
            out=max(out, maximum[j][x]);
            x=ancest[j][x];
            p1=p1-(1<<j);
        }
        while(p2){
            j=int(log2(p2));
            out=max(out, maximum[j][y]);
            y=ancest[j][y];
            p2=p2-(1<<j);
        }
        printf("%d\n", out);
    }
    return;
}
void formcst(int total){
    while(total){
        while(!pq.empty() && inmcst[get<2>(pq.top())]==true) pq.pop();
        if(pq.empty()) break;
        inmcst[get<2>(pq.top())]=true;
        tiii init=pq.top(); --total;
        if(get<1>(init)){
            up[get<2>(init)]=get<0>(init);
            tree[get<1>(init)].push_back(get<2>(init));
            dad[get<2>(init)]=get<1>(init);
        }
        for(auto i:graph[get<2>(init)]){
            if(inmcst[i.node]) continue;
            pq.push(mt(i.cost, get<2>(init), i.node));
        }
    }
    return;
}
void formanc(int node){
    ancest[0][node]=dad[node]; maximum[0][node]=up[node];
    int next=dad[node];
    for(j=1; (1<<j)<=level[node]; ++j){
        ancest[j][node]=ancest[j-1][next];
        maximum[j][node]=max(maximum[j-1][node], maximum[j-1][next]);
        next=ancest[j][node];
    }
    for(auto i:tree[node]){
        dad[i]=node;
        level[i]=level[node]+1;
        formanc(i);
    }
    return;
}
void formlca(int node){
    for(auto i:tree[node]){
        rmq[0][++v]=node;
        if(!first[node]) first[node]=v;
        formlca(i);
    }
    rmq[0][++v]=node;
    if(!first[node]) first[node]=v;
    return;
}
int mn(int node1, int node2){
    if(level[node1]<=level[node2]) return node1;
    return node2;
}