Cod sursa(job #562864)

Utilizator eudanipEugenie Daniel Posdarascu eudanip Data 23 martie 2011 23:28:44
Problema Radiatie Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.09 kb
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;

#define NMAX 15006
#define pi pair< pair<int,int>,int>
#define x first.first
#define y first.second
#define val second
#define mp make_pair
#define maxim(a,b) (a>b ? a : b)
#define pb push_back

vector<int> v[NMAX],cost[NMAX];
int h[NMAX],n,m,k,prep[NMAX],nrb;
int rmq[20][NMAX],rmq2[20][NMAX];
int tata[NMAX],grad[NMAX],viz[NMAX];
int hmax;
pi mc[NMAX];

void dfs(int nod)
{
    int i,vec,lim=v[nod].size();
    viz[nod]=1;
    for(i=0;i<lim;i++)
    {
        vec=v[nod][i];
        if(viz[vec])
            continue;
        h[vec]=h[nod]+1;
        rmq[0][vec]=nod;
        rmq2[0][vec]=cost[nod][i];
        dfs(vec);
    }
}

int find(int nod,int L,int tip)
{
    if(!L)
        return (!tip ? 0 : nod);
    if(!tip)
        return maxim(rmq2[prep[L]][nod],
        find(rmq[prep[L]][nod],L-(1<<prep[L]),0));
    else
        return find(rmq[prep[L]][nod],L-(1<<prep[L]),1);
}

int lca(int n1,int n2)
{
    int i,aux;
    if(h[n1]>=h[n2])
    {
        aux=n1;
        n1=n2;
        n2=aux;
    }
    n2=find(n2,h[n2]-h[n1],1);
    if(n1==n2)
        return n1;
    for(i=nrb;i>=0;i--)
        if(rmq[i][n1]!=rmq[i][n2])
        {
            n1=rmq[i][n1];
            n2=rmq[i][n2];
        }
    return rmq[0][n1];
}

int find_father(int nod)
{
    if(tata[nod]==nod)
        return nod;
    tata[nod]=find_father(tata[nod]);
    return tata[nod];
}

inline int cmp(const pi& a,const pi& b)
{
    return a.val<b.val;
}

int main ()
{
    int i,j,v1,v2,diff;
    int a,b,c,t1,t2;
    
    freopen("radiatie.in","r",stdin);
    freopen("radiatie.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        mc[i]=mp(mp(a,b),c);
    }
    sort(mc+1,mc+m+1,cmp);
    for(i=1;i<=n;i++)
    {
        grad[i]=1;
        tata[i]=i;
    }
    for(i=1;i<=m;i++)
    {
        t1=find_father(mc[i].x);
        t2=find_father(mc[i].y);
        if(t1==t2)
            continue;
        if(grad[t1]>grad[t2])
        {
            tata[t2]=t1;
            grad[t1]+=t2;
        }
        else
        {
            tata[t1]=t2;
            grad[t2]+=grad[t1];
        }
        v[mc[i].x].pb(mc[i].y);
        cost[mc[i].x].pb(mc[i].val);
        
        v[mc[i].y].pb(mc[i].x);
        cost[mc[i].y].pb(mc[i].val);
    }
    dfs(1);
    for(i=1;i<=n;i++)
        hmax=maxim(hmax,h[i]);
        
    for(j=1;(1<<j)<=hmax;j++)
        for(i=1;i<=n;i++)
            if(h[i]>=(1<<j))
            {
                rmq[j][i]=rmq[j-1][rmq[j-1][i]];
                rmq2[j][i]=maxim(rmq2[j-1][i],
                                 rmq2[j-1][rmq[j-1][i]]);
            }
    nrb=j-1;
    for(i=2;i<=hmax;i++)
        prep[i]=prep[i/2]+1;
    for(i=1;i<=k;i++)
    {
        scanf("%d%d",&a,&b);
        c=lca(a,b);
        diff=h[a]-h[c];
        v1=find(a,diff,0);
        diff=h[b]-h[c];
        v2=find(b,diff,0);
        printf("%d\n",maxim(v1,v2));
    }
    return 0;
}