Cod sursa(job #522433)

Utilizator Bogdan_tmmTirca Bogdan Bogdan_tmm Data 15 ianuarie 2011 10:13:49
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.07 kb
#include<algorithm>
#include<vector>

using namespace std;
#define N_MAX 15001
#define M_MAX 30001

int N,M,K;
int i,j,x,y,c;

struct muchie
{
	int x,y,c;
	muchie()
	{
	}
	muchie(const int &a,const int &b,const int &c)
	{
		this->x=a;
		this->y=b;
		this->c=c;
	}
};

struct cmp
{
	bool operator () (const muchie &a,const muchie &b) const
	{
		return a.c<b.c;
	}
};
muchie m[M_MAX];

int tata[N_MAX],grad[N_MAX];

int getRad(int nod)
{
	int root,aux;
	for(root=nod;root!=tata[root];root=tata[root]);

	for(;nod!=root;)
	{
		aux=tata[nod];
		tata[nod]=root;
		nod=aux;
	}
	return root;
}

void uneste(int a,int b)
{
	if(grad[a]<grad[b])
	{
		grad[b]++;
		tata[a]=b;
	}
	else
	{
		grad[a]++;
		tata[b]=a;
	}
}

struct nood
{
	int y,c;
	nood()
	{
	}
	nood(const int &a,const int &b)
	{
		this->y=a;
		this->c=b;
	}
};
vector <nood> arb[N_MAX];

bool ut[N_MAX];
int cost[N_MAX];

vector <int> eul(1);
int rmq[18][N_MAX*2];
int lg[N_MAX*2];
int nivel[N_MAX];
int fPoz[N_MAX];
void euler(int nod,int niv)
{
	vector <nood> ::iterator it;
	eul.push_back(nod);
	nivel[nod]=niv;
	ut[nod]=1;
	for(it=arb[nod].begin();it!=arb[nod].end();it++)
		if(!ut[it->y])
		{
			tata[it->y]=nod;
			cost[it->y]=it->c;
			euler(it->y,niv+1);
			eul.push_back(nod);
		}
}

int str[18][N_MAX];
int maxM[18][N_MAX];

int main()
{
	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",&x,&y,&c);
		m[i]=muchie(x,y,c);
	}

	sort(m+1,m+M+1,cmp());

	for(i=1;i<=N;i++)
		tata[i]=i;

	for(i=1;i<=M;i++)
	{
		x=getRad(m[i].x);
		y=getRad(m[i].y);

		if(x!=y)
		{
			uneste(x,y);
			arb[m[i].x].push_back(nood(m[i].y,m[i].c));
			arb[m[i].y].push_back(nood(m[i].x,m[i].c));
		}
	}

	euler(1,0);

	int nn=eul.size()-1;

	for(i=2;i<=nn;i++)
		lg[i]=lg[i/2]+1;

	for(i=1;i<=nn;i++)
		rmq[0][i]=eul[i];
	
	for(i=nn;i>=1;i--)
		fPoz[eul[i]]=i;

	for(i=1;(1<<i)<nn;i++)
		for(j=1;j+(1<<i)-1<=nn;j++)
		{
			if(nivel[rmq[i-1][j]]<nivel[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(i=1;i<=N;i++)
	{
		str[0][i]=tata[i];
		maxM[0][i]=cost[i];
	}
	for(i=1;i<18;i++)
	{
		for(j=1;j<=N;j++)
		{
			maxM[i][j]=max(maxM[i-1][j],maxM[i-1][str[i-1][j]]);
			str[i][j]=str[i-1][str[i-1][j]];
		}
	}

	for(i=1;i<=K;i++)
	{
		scanf("%d%d",&x,&y);
		int xx=fPoz[x];
		int yy=fPoz[y];
		if(xx>yy)
			swap(xx,yy);
		int dist=yy-xx+1;
		int nod1=rmq[lg[dist]][xx];
		int nod2=rmq[lg[dist]][yy-(1<<lg[dist])+1];
		if(nivel[nod1]>nivel[nod2])
			nod1=nod2;
		
		dist=nivel[x]-nivel[nod1];
		int Max=0;
		int log=0;
		while(x!=nod1)
		{
			if(dist%2)
			{
				Max=max(Max,maxM[log][x]);
				x=str[log][x];
			}
			log++;
			dist>>=1;
		}
		
		log=0;
		dist=nivel[y]-nivel[nod1];
		while(y!=nod1)
		{
			if(dist%2)
			{
				Max=max(Max,maxM[log][y]);
				y=str[log][y];
			}
			log++;
			dist>>=1;
		}
		printf("%d\n",Max);
	}
	return 0;
}