Cod sursa(job #1277549)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 27 noiembrie 2014 20:14:49
Problema Radiatie Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.47 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#define Nmax 100005

using namespace std;

struct el
{
    int x,y,cost;
    bool operator <(const el &A) const
    {
        return cost<A.cost;
    }
};
el v[Nmax];
int t[Nmax];
bool viz[Nmax];

int n,top,poz[Nmax],nivel[Nmax],st[Nmax],dp[Nmax][20],lg[Nmax],d[Nmax][20],stramos[Nmax][20],N;

struct Edge
{
    int nod,cost;
};
vector <Edge> L[Nmax];
Edge father[Nmax];

inline void Dfs(int nod, int tata, int niv)
{
    Edge w;
    st[++top]=nod; nivel[nod]=niv; poz[nod]=top;
    vector <Edge> ::iterator it;
    for(it=L[nod].begin();it!=L[nod].end();++it)
        if(it->nod!=tata)
        {
            w.nod=nod; w.cost=it->cost;
            father[it->nod]=w;
            Dfs(it->nod,nod,niv+1);
            st[++top]=nod;
        }
}

inline void RMQ()
{
    int i,j;
    for(i=1;i<=n;++i) dp[i][0]=i;
    for(j=1;j<=20;++j)
        for(i=n;i;--i)
        {
            if(i+(1<<j)-1>n) continue;
            if(nivel[st[dp[i][j-1]]]<nivel[st[dp[i+(1<<(j-1))][j-1]]])
                dp[i][j]=dp[i][j-1];
            else
                dp[i][j]=dp[i+(1<<(j-1))][j-1];
        }
}

inline void Prec()
{
    int i;
    lg[1]=0;
    for(i=2;i<=n;++i)
        lg[i]=lg[i/2]+1;
}

inline int Query(int x, int y)
{
    int l=y-x+1,p,t;
    p=lg[l]; t=(1<<p);
    if(nivel[st[dp[x][p]]]<nivel[st[dp[y+1-t][p]]]) return st[dp[x][p]];
    return st[dp[y+1-t][p]];
}

inline void Unite(int a, int b)
{
    t[a]+=t[b]; t[b]=a;
}

inline int Find(int a)
{
    int rad,i=a;
    while(t[a]>0)
        a=t[a];
    rad=a;
    while(t[i]>0)
    {
        a=t[i];
        t[i]=rad;
        i=a;
    }
    return rad;
}

inline void RMQ1()
{
    int i,j;
    for(i=1;i<=N;++i)
        stramos[i][0]=father[i].nod;
    for(j=1;j<=20;++j)
        for(i=1;i<=N;++i)
        {
            if(nivel[i]-1<(1<<j)) continue;
            stramos[i][j]=stramos[stramos[i][j-1]][j-1];
        }
    for(i=1;i<=N;++i)
        d[i][0]=father[i].cost;
    for(j=1;j<=20;++j)
        for(i=1;i<=N;++i)
        {
            if(nivel[i]-1<(1<<j)) continue;
            d[i][j]=max(d[i][j-1],d[stramos[i][j-1]][j-1]);
        }
}

inline int Query1(int x, int y)
{
    int dist=nivel[x]-nivel[y],sol=0,i;
    for(i=20;i>=0 && dist;--i)
    {
        if((1<<i)>dist) continue;
        sol=max(sol,d[x][i]);
        x=stramos[x][i]; dist-=(1<<i);
    }
    return sol;
}

int main()
{
    int x,y,i,k,m,lca,xx,yy;
    Edge w;
    freopen ("radiatie.in","r",stdin);
    freopen ("radiatie.out","w",stdout);
    scanf("%d%d%d", &n,&m,&k);
    N=n;
    for(i=1;i<=m;++i)
        scanf("%d%d%d", &v[i].x,&v[i].y,&v[i].cost);
    sort(v+1,v+m+1);
    for(i=1;i<=n;++i) t[i]=-1;
    for(i=1;i<=m;++i)
    {
        x=Find(v[i].x); y=Find(v[i].y);
        if(x!=y)
        {
            Unite(x,y);
            viz[i]=true;
        }
    }
    for(i=1;i<=n;++i) L[i].clear();
    for(i=1;i<=n;++i)
        if(viz[i])
        {
            w.nod=v[i].y; w.cost=v[i].cost;
            L[v[i].x].push_back(w);
            w.nod=v[i].x; w.cost=v[i].cost;
            L[v[i].y].push_back(w);
        }

    Dfs(1,0,1);
    n=top;
    Prec();
    RMQ();
    RMQ1();
    while(k--)
    {
        scanf("%d%d", &x,&y);
        xx=poz[x]; yy=poz[y];
        lca=Query(min(xx,yy),max(xx,yy));
        printf("%d\n", max(Query1(x,lca),Query1(y,lca)));
    }
    return 0;
}