Cod sursa(job #133024)

Utilizator megabyteBarsan Paul megabyte Data 7 februarie 2008 12:42:25
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#define INF "radiatie.in"
#define OUF "radiatie.out"
#define pb push_back
#define sz(arg) arg.size()


using namespace std;
const int NMAX=16002;
const int MMAX=30002;
const int BIG=2000000000;
const int LG=16;

struct arc
{
	short x,y;
	int l;
};
struct arc2
{
	short nb;
	int l;
};

short n,m,k,niv[NMAX]={0},t[NMAX][LG]={0},rang[NMAX]={0},up[NMAX]={0};
int best[NMAX][LG]={0},vx;
char viz[NMAX]={0};

vector<arc2> a[NMAX];//ARBORE
vector<arc> ed;

void init(short x)
{
	up[x]=x;
	rang[x]=0;
}

short cauta(short x)
{
	if(x!=up[x]) up[x]=cauta(up[x]);
	return up[x];
}

void uneste(short x,short y)
{
	if(rang[x]>rang[y])	up[y]=x;
	else
	{
		up[x]=y;
		if(rang[x]==rang[y]) rang[y]++;
	}
}


bool cmp(arc alfa,arc beta) {return (alfa.l<beta.l);}

void apm()
{
	sort(ed.begin(),ed.end(),cmp);
	short i,nbx,nby,nr;
	arc2 ab;
	
	for(i=1;i<=n;++i) init(i);//componenta conexa in care este i

	i=0;nr=n-1;
	while(nr>0&&i<m)
	{
		while(i<m&&cauta(ed[i].x)==cauta(ed[i].y)) ++i;
		nbx=ed[i].x;nby=ed[i].y;
		ab.l=ed[i].l;
		ab.nb=nby;a[nbx].push_back(ab);
		ab.nb=nbx;a[nby].push_back(ab);
		
		uneste(cauta(nbx),cauta(nby));
		--nr;
	}
}

void dfs(short nd,short lev)
{
	short i,nb,j;
	viz[nd]=1;niv[nd]=lev;
	for(i=0;i<sz(a[nd]);++i)
	if(!viz[a[nd][i].nb]) 
	{
		nb=a[nd][i].nb;
		t[nb][0]=nd;best[nb][0]=a[nd][i].l;
		for(j=1;(1<<j)<=n;++j)
		{
			t[nb][j]=t[t[nb][j-1]][j-1];
			if(!t[nb][j]) break;
			best[nb][j]=max(best[nb][j-1],best[t[nb][j-1]][j-1]);
		}
		dfs(nb,lev+1);
	}
}

short way(short nd,short nr)
{
	short i,p;
	p=nd; i=0; 
	while(nr)
	if((1<<i)&nr)
	{
		p=t[p][i];
	//	printf("%hd %hd\n",i,p);
		nr-=(1<<i);
		++i;
	}
	else ++i;
	return p;
}

int wmax(short nd,short nr)
{
	short i=0;
	int ret=-1;
	while(nr)
	if(nr&(1<<i))
	{
		if(best[nd][i]>ret) ret=best[nd][i];
		nd=t[nd][i];
//		printf("%hd %hd %d\n",nd,i,ret);
		nr-=(1<<i);
		++i;
	}
	else ++i;
	return ret;
}

int query(short x,short y)
{
	int mx,opt;
	short q,p,st,dr,mij,lca=1;
	if(niv[x]<niv[y]) dr=niv[x];
	else dr=niv[y];
	st=1;//LCA SE AFLA PE NIV 1
	while(st<=dr)
	{
		mij=(st+dr)/2;
		p=way(x,(niv[x]-mij));
		q=way(y,(niv[y]-mij));
		if(p==q) { st=mij+1;lca=p; }
	        else dr=mij-1;	
	}
	//printf("%hd %hd %hd\n",x,y,lca);
	opt=wmax(x,(niv[x]-niv[lca]));
	mx=wmax(y,(niv[y]-niv[lca]));
        //printf("%d %d\n",mx,opt);	
	return max(opt,mx);
}

int main()
{
	FILE *in,*out;
	in=fopen(INF,"r");
	out=fopen(OUF,"w");
	short i,j,alfa,beta;
	arc x;
	fscanf(in,"%hd%hd%hd",&n,&m,&k);
	for(i=0;i<m;++i)
	{
		fscanf(in,"%hd%hd%d",&x.x,&x.y,&x.l);
		ed.push_back(x);
	}

	apm();

	dfs(1,1);
/*	for(i=0;i<=n;++i)
	{
		for(j=0;j<LG;++j) printf("%hd ",best[i][j]);
		printf("\n");
	}*/
	
	for(i=1;i<=k;++i)
	{
		fscanf(in,"%hd%hd",&alfa,&beta);
		fprintf(out,"%d\n",query(alfa,beta));
	}
	fclose(in);fclose(out);
	return 0;
}