Cod sursa(job #1783388)

Utilizator TibiraducanuTiberiu Raducanu Tibiraducanu Data 18 octombrie 2016 23:10:05
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.64 kb
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

const int N=15005, M=30005;
int n,m,k,t[N],h[N],viz[N],niv[N],d[N][17], Max[N][17];
struct muchie{
    int a,b,c;
} v[M],sol[N];

typedef pair<int,int> ii;
vector <ii> G[N];
ii T[N];

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

int Find(int x){
    if(x==t[x]) return x;
    t[x]=Find(t[x]);
    return t[x];
}
void Union(int a,int b){
    if(h[a]>h[b]) t[b]=a;
    else {
        t[a]=b;
        if(h[a]==h[b]) h[b]++;
    }
}

void dfs(int x){
    viz[x]=1;
    for(int i=0;i<(int)G[x].size();i++){
        int y=G[x][i].first;
        if(viz[y]==0){
            niv[y]=niv[x]+1;
            T[y].first=x;
            T[y].second=G[x][i].second;
            dfs(y);
        }
    }
}

int Lca(int x, int y){
    if(niv[x]<niv[y]) swap(x,y);
    int Val=niv[x]-niv[y];
    for(int i=0;i<=15;i++)
        if(Val&(1<<i)) x=d[x][i];

    if(x==y) return x;

    for(int i=15;i>=0;i--)
        if(d[x][i]!=d[y][i]){
            x=d[x][i];
            y=d[y][i];
        }

    return d[x][0];
}


int main(){
    freopen("radiatie.in","r",stdin);
    freopen("radiatie.out","w",stdout);

    int i,j,cnt=0,x,y,z;

    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=n;i++) t[i]=i;
    for(i=1;i<=m;i++)
        scanf("%d%d%d",&v[i].a,&v[i].b,&v[i].c);

    sort(&v[1],&v[m+1],cmp);
    for(i=1;i<=m;i++){
        if(cnt==n-1) break;
        x=Find(v[i].a);
        y=Find(v[i].b);

        if(x!=y){
            Union(x,y);
            cnt++;
            sol[cnt]=v[i];
        }
    }

    for(i=1;i<=n-1;i++){
        G[sol[i].a].push_back(ii(sol[i].b,sol[i].c));
        G[sol[i].b].push_back(ii(sol[i].a,sol[i].c));
    }

    for(i=1;i<=n;i++)
        if(viz[i]==0){
            niv[i]=1;
            dfs(i);
        }

    for(i=1;i<=n;i++){
        d[i][0]=T[i].first;
        Max[i][0]=T[i].second;
    }

    for(j=1;j<=15;j++)
        for(i=1;i<=n;i++){
            d[i][j]=d[d[i][j-1]][j-1];
            Max[i][j]=max(Max[i][j-1],Max[d[i][j-1]][j-1]);
        }

    int One,Two,Max1,Max2;

    for(i=1;i<=k;i++){
        scanf("%d%d",&x,&y);
        z=Lca(x,y);
        One=niv[x]-niv[z];
        Two=niv[y]-niv[z];
        Max1=0,Max2=0;

        for(j=0;j<=15;j++){
            if(One&(1<<j)){
                Max1=max(Max1,Max[x][j]);
                x=d[x][j];
            }
            if(Two&(1<<j)){
                Max2=max(Max2,Max[y][j]);
                y=d[y][j];
            }
        }
        printf("%d\n",max(Max1,Max2));
    }

    return 0;
}