Cod sursa(job #1813487)

Utilizator andreicoman299Coman Andrei andreicoman299 Data 22 noiembrie 2016 23:23:24
Problema Radiatie Scor 100
Compilator cpp Status done
Runda cerculdeinfo-lectia7-grafuri Marime 4.05 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>

#define BUF_SIZE 16384
char buf[BUF_SIZE];
int pbuf=BUF_SIZE;
FILE*fi,*fo;
inline char nextch(){
    if(pbuf==BUF_SIZE){
        fread(buf, BUF_SIZE, 1, fi);
        pbuf=0;
    }
    return buf[pbuf++];
}
inline long long nextnum(){
    long long a=0;
    char c=nextch();
    while((c<'0' || c>'9') && c!='-')
        c=nextch();
    int semn=1;
    if(c=='-'){
        semn=-1;
        c=nextch();
    }
    while('0'<=c && c<='9'){
        a=a*10+c-'0';
        c=nextch();
    }
    return a*semn;
}

#define MAXM 30000
#define MAXN 15000
#define MAXL 17

int maxdepth=0;
struct muchie{
    int left;
    int right;
    int cost;
} M[1+MAXM];
int cmpM(muchie A, muchie B){
    return (A.cost<B.cost);
}

struct Edge{
    int dest;
    int cost;
};
int fth[1+MAXN];
std::vector <Edge> G[1+MAXN];

inline int Union(int a, int b){
    fth[b]=a;
}
int Find(int x){
    if(fth[x]==x)
        return x;
    int y=Find(fth[x]);
    fth[x]=y;
    return y;
}

int euler[2*MAXN], ind;
int depth[2*MAXN];
int h[1+MAXN];
int firstapp[1+MAXN];
void getEuler(int node, int fth, int d){
    if(d>maxdepth)
        maxdepth=d;
    euler[++ind]=node;
    depth[ind]=d;
    h[node]=d;
    firstapp[node]=ind;
    for(int i=0;i<G[node].size();i++)
        if(G[node][i].dest!=fth){
            getEuler(G[node][i].dest, node, d+1);
            euler[++ind]=node;
            depth[ind]=d;
        }
}

int rmq[MAXL][2*MAXN];
int lg[2*MAXN];
void getRmq(){
    for(int i=2;i<=ind;i++)
        lg[i]=lg[i/2]+1;
    for(int i=1;i<=ind;i++)
        rmq[0][i]=i;
    for(int i=1;(1<<i)<ind;i++)
        for(int j=1;j<=ind-(1<<i);j++){
            int l=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if(depth[rmq[i-1][j+l]]<depth[rmq[i][j]])
                rmq[i][j]=rmq[i-1][j+l];
        }
}
inline int lca(int x, int y){
    int a=firstapp[x], b=firstapp[y];
    if(a>b){int aux=a;a=b;b=aux;}
    int diff=b-a+1;
    int l=lg[diff];
    int sol=rmq[l][a];
    int sh=diff-(1<<l);
    if(depth[sol]>depth[rmq[l][a+sh]])
        sol=rmq[l][a+sh];
    return euler[sol];
}

struct A{
    int node;
    int val;
} dp[MAXL][1+MAXN];
inline int maxim(int a, int b){
    return a > b ? a : b;
}
inline int getRoad(int n){
    for(int i=1;i<=n;i++)
        for(int j=0;j<G[i].size();j++)
            if(h[i]>h[G[i][j].dest]){
                dp[0][i].node=G[i][j].dest;
                dp[0][i].val=G[i][j].cost;
            }
    for(int log=1;(1<<log)<=maxdepth;log++)
        for(int i=1;i<=n;i++){
            dp[log][i].node=dp[log-1][dp[log-1][i].node].node;
            dp[log][i].val=maxim(dp[log-1][i].val, dp[log-1][dp[log-1][i].node].val);
        }
}
inline int maxOnRoad(int node, int height){
    int max=0;
    int log=0;
    while((1<<log)<=height){
        if(height&(1<<log)){
            max=maxim(max, dp[log][node].val);
            node=dp[log][node].node;
        }
        log++;
    }
    return max;
}

int main(){
    fi=fopen("radiatie.in","r");
    fo=fopen("radiatie.out","w");
    int n=nextnum(), m=nextnum(), k=nextnum();
    for(int i=1;i<=m;i++){
        M[i].left=nextnum();
        M[i].right=nextnum();
        M[i].cost=nextnum();
    }
    std::sort(M+1, M+m+1, cmpM);
    for(int i=1;i<=n;i++)
        fth[i]=i;
    for(int i=1;i<=m;i++)
        if(Find(M[i].left)!=Find(M[i].right)){
            Edge temp;
            temp.dest=M[i].right;
            temp.cost=M[i].cost;
            G[M[i].left].push_back(temp);
            temp.dest=M[i].left;
            G[M[i].right].push_back(temp);
            Union(Find(M[i].left), Find(M[i].right));
        }
    int root=1;
    getEuler(root, 0, 1);
    getRmq();
    getRoad(n);
    for(int i=0;i<k;i++){
        int a=nextnum(), b=nextnum();
        int l=lca(a, b);
        fprintf(fo,"%d\n", maxim(maxOnRoad(a, h[a]-h[l]), maxOnRoad(b, h[b]-h[l])));
    }
    fclose(fi);
    fclose(fo);
    return 0;
}