Cod sursa(job #2128646)

Utilizator vancea.catalincatalin vancea.catalin Data 11 februarie 2018 21:46:14
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
#include<algorithm>
#include<iostream>
#include<fstream>
#include<cstring>
#include<vector>
#define DNK 15100 // log2(16384)=14
#define DM 30100
 
using namespace std;
fstream fin("radiatie.in",ios::in), fout("radiatie.out",ios::out);
 
int n,m,k,st[DNK],apm[DM],niv[DNK],dp[15][DNK],dpc[15][DNK],lg2[DNK];
vector<pair<int,int>> v[DNK];
 
struct str {
    int x,y,r;
} muc[DM];
 
bool cmp(str a,str b) {
    if(a.r<b.r) return 1;
    return 0;
}
 
int stramos(int nod) {
    if(st[nod]==nod) return nod;
    return (st[nod]=stramos(st[nod]));
}
 
void dfs(int nod,int nivel){
    niv[nod]=nivel;
    for(auto x: v[nod]){
        if(dp[0][nod]==x.first) continue;
        dp[0][x.first]=nod;
        dpc[0][x.first]=x.second;
        dfs(x.first,nivel+1);
    }
}
 
int salt(int nod,int pas)
{
    int bit,lg;
    while(pas!=0)
    {
        bit=pas-(pas&(pas-1));
        lg=lg2[bit];
        nod=dp[lg][nod];
        pas-=bit;
    }
    return nod;
}
 
int lca(int x,int y)
{
    if(niv[x]>niv[y]) swap(x,y);
    int a,b,dif=niv[y]-niv[x],pas=13;
    y=salt(y,dif);
     
    if(x==y) return x;
    while(pas>=0)
    {
        a=salt(x,(1<<pas));
        b=salt(y,(1<<pas));
        if(a!=0 && a!=b)
        {
            x=a;
            y=b;
        }
        pas--;
    }
    return dp[0][x];
}
int rmax(int x,int y,int l)
{
    int bit,dif,lg,rm=0;
     
    //salt de la x la l
    dif=niv[x]-niv[l];
    while(dif>0)
    {
        bit=dif-(dif&(dif-1));
        lg=lg2[bit];
        rm=max(rm,dpc[lg][x]);
        x=dp[lg][x];
        dif-=bit;
    }
     
    //salt de la y la l
    dif=niv[y]-niv[l];
    while(dif>0)
    {
        bit=dif-(dif&(dif-1));
        lg=lg2[bit];
        rm=max(rm,dpc[lg][y]);
        y=dp[lg][y];
        dif-=bit;
    }
    return rm;
}
 
int main()
{
    int a,b,c,d,i,j,x,y,l,r;
    fin>>n>>m>>k; 
    for(i=1;i<=n;i++) st[i]=i;
    for(i=1;i<=m;i++) fin>>muc[i].x>>muc[i].y>>muc[i].r;
     
    sort(muc+1, muc+m+1, cmp);
    for(i=1;i<=m;i++) // aflam muchiile arborelui
    {
        a=muc[i].x; b=muc[i].y;
        c=stramos(a); d=stramos(b);
        if(c==d) continue ;
        apm[i]=1;
        st[c]=d;
    }
 
    for(i=1;i<=m;i++) //construim arborele
    {
        if(apm[i]==1)
        {
            a=muc[i].x; b=muc[i].y; c=muc[i].r;
            v[a].push_back({b,c});
            v[b].push_back({a,c});
        }
    }
     
     
    for(i=0;i<=13;i++) lg2[(1<<i)]=i;
    for(i=1;i<DNK;i++) lg2[i]=max(lg2[i-1],lg2[i]);
     
    dfs(1,1);
     
    for(i=1;i<=13;i++)
    {
        for(j=1;j<=n;j++)
        {   
            dp[i][j]=dp[i-1][dp[i-1][j]];
            dpc[i][j]=max(dpc[i-1][j],dpc[i-1][dp[i-1][j]]);
        }
    }
     
    for(i=1;i<=k;i++)
    {
        fin>>x>>y;
        l=lca(x,y);
        r=rmax(x,y,l);
        //cout<<x<<" "<<y<<" "<<l<<" "<<r<<"\n";
        fout<<r<<"\n";
    }
     
}