Cod sursa(job #48267)

Utilizator sealTudose Vlad seal Data 4 aprilie 2007 16:22:33
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include<stdio.h>
#include<stdlib.h>
#define Nm 15001
#define Lognm 14
#define max(a,b) ((a)>(b)?(a):(b))

int *G[Nm],*C[Nm],D[Nm],n;
int X[Nm],Y[Nm],k,m;
int A[Lognm][Nm],Max[Lognm][Nm],Niv[Nm],Arb[2*Nm],T[Nm];
struct muchie
{
    int x,y,c;
} M[2*Nm];

void read()
{
    int i;

    freopen("radiatie.in","r",stdin);
    scanf("%d%d%d",&n,&m,&k);
    for(i=0;i<m;i++)
	scanf("%d%d%d",&M[i].x,&M[i].y,&M[i].c);
    for(i=0;i<k;i++)
	scanf("%d%d",X+i,Y+i);
}

int cmp(const void *x, const void *y)
{
    return ((muchie*)x)->c-((muchie*)y)->c;
}

int Find(int x)
{
    while(T[x]>0)
	x=T[x];
    return x;
}

void Union(int x, int y)
{
    if(T[x]<T[y])
	T[y]=x;
    else
    {
	if(T[x]==T[y])
	    T[y]--;
	T[x]=y;
    }
}

void DFS(int x, int tx, int c)
{
    int i;

    Niv[x]=Niv[tx]+1;
    A[0][x]=tx;
    Max[0][x]=c;
    for(i=1;1<<i<n;i++)
	if(A[i-1][A[i-1][x]])
	{
	    A[i][x]=A[i-1][A[i-1][x]];
	    Max[i][x]=max(Max[i-1][x],Max[i-1][A[i-1][x]]);
	}
	else
	    break;

    for(i=0;i<D[x];i++)
	if(!Niv[G[x][i]])
	    DFS(G[x][i],x,C[x][i]);
}

void solve()
{
    int i,j,mx,my;

    qsort(M,m,sizeof(muchie),cmp);
    for(i=0;i<m;i++)
    {
	mx=Find(M[i].x);
	my=Find(M[i].y);
	if(mx!=my)
	{
	    Arb[i]=1;
	    Union(mx,my);
	}
    }

    for(i=0;i<m;i++)
	if(Arb[i])
	{
	    D[M[i].x]++;
	    D[M[i].y]++;
	}
    for(i=1;i<=n;i++)
    {
	G[i]=(int*)malloc(D[i]*sizeof(int));
	C[i]=(int*)malloc(D[i]*sizeof(int));
	D[i]=0;
    }
    for(i=0;i<m;i++)
	if(Arb[i])
	{
	    G[M[i].x][D[M[i].x]]=M[i].y;
	    C[M[i].x][D[M[i].x]]=M[i].c;
	    D[M[i].x]++;
	    G[M[i].y][D[M[i].y]]=M[i].x;
	    C[M[i].y][D[M[i].y]]=M[i].c;
	    D[M[i].y]++;
	}

    for(i=1;i<=n;i++)
	if(!Niv[i])
	{
	    Niv[i]=1;
	    for(j=0;j<D[i];j++)
		DFS(G[i][j],i,C[i][j]);
	}
}

int cost_max(int x, int y)
{
    int i,j,cm=0;

    if(Niv[x]>Niv[y])
    {
	x=x^y;
	y=x^y;
	x=x^y;
    }

    j=Niv[y]-Niv[x];
    for(i=0;1<<i<=j;i++)
	if((1<<i&j)!=0)
	{
	    cm=max(cm,Max[i][y]);
	    y=A[i][y];
	}

    i=0;
    while(1<<i+1<n)
	i++;

    while(x!=y)
    {
	for(;i>=0 && A[i][x]==A[i][y];i--);
	if(i>=0)
	{
	    cm=max(cm,Max[i][x]);
	    x=A[i][x];
	    cm=max(cm,Max[i][y]);
	    y=A[i][y];
	}
	cm=max(cm,Max[0][x]);
	x=A[0][x];
	cm=max(cm,Max[0][y]);
	y=A[0][y];
    }

    return cm;
}

void write()
{
    int i;

    freopen("radiatie.out","w",stdout);
    for(i=0;i<k;i++)
	printf("%d\n",cost_max(X[i],Y[i]));
}

int main()
{
    read();
    solve();
    write();
    return 0;
}