Cod sursa(job #2129324)

Utilizator stelian2000Stelian Chichirim stelian2000 Data 12 februarie 2018 18:53:35
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

struct str
{
    int x,y,c;
};

str g[30010];
int rad[15010],logg[30010],niv[15010],first[15010],rmq[20][30010],d[16][15010],t[16][15010],l;
vector<pair<int,int>> v[15010];

int cmp(str a,str b)
{
    return a.c<b.c;
}

int radacina(int x)
{
    if(x==rad[x]) return x;
    return radacina(rad[x]);
}

void uneste(int a,int b)
{
    int x=radacina(a),y=radacina(b);
    rad[x]=y;
}

void dfs(int nod,int tata,int nivel)
{
    niv[nod]=nivel;
    rmq[0][++l]=nod;
    first[nod]=l;
    for(int i=0;i<v[nod].size();i++)
        if(v[nod][i].first!=tata)
        {
            d[0][v[nod][i].first]=v[nod][i].second;
            t[0][v[nod][i].first]=nod;
            dfs(v[nod][i].first,nod,nivel+1);
            rmq[0][++l]=nod;
        }
}

int lca(int x,int y)
{
    x=first[x];
    y=first[y];
    if(x>y) swap(x,y);
    int l1=logg[y-x+1];
    if(niv[rmq[l1][x]]<niv[rmq[l1][y-(1<<l1)+1]]) return rmq[l1][x];
    else return rmq[l1][y-(1<<l1)+1];
}

int main()
{
    freopen("radiatie.in","r",stdin);
    freopen("radiatie.out","w",stdout);
    int n,m,k,x,y;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++) scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].c);
    sort(g+1,g+m+1,cmp);
    for(int i=1;i<=n;i++) rad[i]=i;
    int nr=0;
    for(int i=1;i<=m;i++)
        if(radacina(g[i].x)!=radacina(g[i].y))
        {
            v[g[i].x].push_back({g[i].y,g[i].c});
            v[g[i].y].push_back({g[i].x,g[i].c});
            nr++;
            uneste(g[i].x,g[i].y);
            if(nr==n-1) break;
        }
    dfs(1,0,0);
    logg[1]=0;
    for(int i=2;i<=l;i++) logg[i]=logg[i/2]+1;
    for(int i=1;i<=logg[l];i++)
        for(int j=1;j+(1<<i)<=l+1;j++)
            if(niv[rmq[i-1][j]]<niv[rmq[i-1][j+(1<<(i-1))]]) rmq[i][j]=rmq[i-1][j];
            else rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
    for(int i=1;(1<<i)<=n;i++)
        for(int j=1;j<=n;j++)
            t[i][j]=t[i-1][t[i-1][j]];
    for(int i=1;(1<<i)<=n;i++)
        for(int j=1;j<=n;j++)
            d[i][j]=max(d[i-1][j],d[i-1][t[i-1][j]]);
    for(int i=1;i<=k;i++)
    {
        scanf("%d%d",&x,&y);
        int a=lca(x,y);
        int l=niv[x]-niv[a],sol=0;
        for(int bit=15;bit>=0;bit--)
            if(l&(1<<bit)) {sol=max(sol,d[bit][x]);x=t[bit][x];}
        l=niv[y]-niv[a];
        for(int bit=15;bit>=0;bit--)
            if(l&(1<<bit)) {sol=max(sol,d[bit][y]);y=t[bit][y];}
        printf("%d\n",sol);
    }
    return 0;
}