Cod sursa(job #584959)

Utilizator cdascaluDascalu Cristian cdascalu Data 27 aprilie 2011 15:53:30
Problema Radiatie Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include<fstream>
#include<algorithm>
#include<vector>
#include<bitset>
#define Nmax 15001
#define Mmax 30001
#define lgMax 12
using namespace std;
int N,M,K,R[Nmax],T[Nmax],H[Nmax<<2],L[Nmax<<2],lg[Nmax<<2],rmq[lgMax][Nmax<<2],k,lev,loc[Nmax];
int B[lgMax][Nmax],s[lgMax][Nmax];//B[i][j] - cel mai mare cost de la j pana la 2^i stramos
//s[i][j] al 2^i-lea stramosal lui j
struct muchie
{
	int x,y,c;
}m[Mmax];
struct tata
{
	int x,c;
}t[Nmax];
vector< pair<int,int> > G[Nmax];
bitset<Nmax> viz;
int cmp(muchie a,muchie b)
{
	return (a.c<b.c);
}
void compress(int val,int father)
{
	int aux;
	while(val!=T[val])
	{
		aux = T[val];
		T[val] = father;
		val = aux;
	}
}
void unite(int x,int y)
{
	if(R[x]>=R[y])
	{
		R[x]+=R[y];
		T[y] = x;
	}
	else
	{
		R[y]+=R[x];
		T[x] = y;
	}
}
int find(int x)
{
	int init = x;
	while(T[x]!=x)
		x = T[x];
	compress(init,x);
	return x;
}
void apm()
{
	int i,x,y,c;
	for(i=1;i<=N;++i)
	{
		T[i] = i;
		R[i] = 1;
	}
	for(i=1;i<=M;++i)
		if(find(m[i].x)!=find(m[i].y))
		{
			x = m[i].x;
			y = m[i].y;
			c = m[i].c;
			G[x].push_back(make_pair(y,c));
			G[y].push_back(make_pair(x,c));
			unite(find(x),find(y));
		}
}
void df(int nod)
{
	++lev;
	H[++k] = nod;
	loc[nod] = k;
	L[k] = lev;
	for(vector< pair<int,int> >::iterator it = G[nod].begin();it!=G[nod].end();++it)
		if(!viz[it->first])
		{
			viz[it->first] = 1;
			t[it->first].x = nod;
			t[it->first].c = it->second;
			df(it->first);
			H[++k] = nod;
			L[k] = lev;
		}
	--lev;
}
void RMQ()
{
	int i,j;
	for(i=2;i<=k;++i)
		lg[i]=lg[i/2]+1;
	
	for(i=1;i<=k;++i)
		rmq[0][i]=i;
	int put;
	for(j=1;(1<<j) <= k;++j)
		for(i=1;i+(1<<j)-1<=k;++i)
		{
			put = 1<<(j-1);
			rmq[j][i] = rmq[j-1][i];
			if(L[ rmq[j][i] ] > L[ rmq[j-1][i+put] ])
				rmq[j][i] = rmq[j-1][i+put];
		}
	for(i=1;i<=N;++i)
	{
		s[0][i] = t[i].x;
		B[0][i] = t[i].c;
	}
	for(i=1;(1<<i) <= N;++i)
		for(j=1;j+(1<<i)-1<=k;++j)
		{
			s[i][j] = s[i-1][ s[i-1][j] ];
			B[i][j] = max(B[i-1][j], B[i-1][ s[i-1][j] ]);
		}
}
int lca(int x,int y)
{
	x = loc[x];
	y = loc[y];
	if(x>y)
		swap(x,y);
	
	int l = lg[y-x+1],sol;
	sol	= rmq[l][x];
	if(L[sol] > L[rmq[l][y-(1<<l)+1]])
		sol = rmq[l][y-(1<<l)+1];
	
	return H[sol];
}
int stramos(int x,int p)
{
	while(p)
	{
		x = s[lg[p]][x];
		p-=1<<lg[p];
	}
	return x;
}
int main()
{
	ifstream f("radiatie.in");
	f>>N>>M>>K;
	int a,b,c,i;
	for(i=1;i<=M;++i)
	{
		f>>a>>b>>c;
		m[i].x = a;
		m[i].y = b;
		m[i].c = c;
	}
	sort(m+1,m+M+1,cmp);
	apm();
	viz[1] = 1;
	df(1);
	RMQ();
	ofstream g("radiatie.out");
	int dist,distp,nod;
	while(K--)
	{
		f>>a>>b;
		c = lca(a,b);
		i = 0;
		// pe ramura c->a
		if(a!=c)
		{
		dist = L[loc[a]] - L[loc[c]];//distanta intre cele 2 noduri
		distp = lg[dist];
		i = max(i,B[distp][a]);//max pornind din a pana la al 2^distp stramos
		nod = stramos(a, dist-(1<<distp));//nod a.i. nod+2^distp == c
		i = max(i,B[distp][nod]);
		}
		
		//pe ramura c->b
		if(b!=c)
		{
		dist =  L[loc[b]] - L[loc[c]];//distanta intre cele 2 noduri
		distp = lg[dist];
		i = max(i,B[distp][b]);//max pornind din b pana la al 2^distp stramos
		nod = stramos(b, dist-(1<<distp));//nod a.i. nod+2^distp == c
		i = max(i,B[distp][nod]);
		}
		g<<i<<"\n";
	}
	g.close();
	return 0;
}