Cod sursa(job #1018908)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 30 octombrie 2013 08:58:39
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include<fstream>
#include<cstdio>
#include<vector>
#define pii pair<int,int>
using namespace std;
int n,m,K,tata[15010],height[15010],put[15010],stramos[15][15010],best[15][15010],cost[15010],niv[15010];
struct Muchie{
	int x,y,c;
	bool operator <(const Muchie &A) const
	{
		return c<A.c;
	}
};
Muchie M[30100];
vector <pii> G[15010];

inline void Citire()
{
	int i;
	freopen("radiatie.in","r",stdin);
	scanf("%d %d %d",&n,&m,&K);
	for(i=1;i<=m;i++)
		scanf("%d %d %d",&M[i].x,&M[i].y,&M[i].c);
}

inline int Find(int x)
{
	int r,y,aux;
	r=x;
	while(tata[r])
		r=tata[r];
	y=x;
	while(y!=r)
	{
		aux=tata[y];
		tata[y]=r;
		y=aux;
	}
	return r;
}

inline void Union(int x,int y)
{
	if(height[x]<height[y])
		tata[x]=y;
	else
	{
		tata[y]=x;
		if(height[x]==height[y])
			height[x]++;
	}
}

inline void Kruskal()
{
	int i,nr,A,B;
	sort(M+1,M+m+1);
	for(i=1,nr=1;i<=m && nr<n;i++)
	{
		A=Find(M[i].x);
		B=Find(M[i].y);
		if(A!=B)
		{
			nr++;
			Union(A,B);
			G[M[i].x].push_back(make_pair(M[i].y,M[i].c));
			G[M[i].y].push_back(make_pair(M[i].x,M[i].c));
		}
	}
}

inline void DFS(int x,int father,int lvl)
{
	niv[x]=lvl;
	vector <pii>::iterator it;
	for(it=G[x].begin();it!=G[x].end();it++)
		if((*it).first!=father)
		{
			tata[(*it).first]=x;
			cost[(*it).first]=(*it).second;
			DFS((*it).first,x,lvl+1);
		}
}

inline void Stramosi()
{
	int i,j;
	tata[1]=0;
	DFS(1,0,1);
	put[1]=0;
	for(i=2;i<=n;i++)
		put[i]=put[i/2]+1;
	for(i=1;i<=n;i++)
	{
		stramos[0][i]=tata[i];
		best[0][i]=cost[i];
	}
	for(j=1;(1<<j)<=n;j++)
	{
		for(i=1;i<=n;i++)
		{
			stramos[j][i]=stramos[j-1][stramos[j-1][i]];
			best[j][i]=max(best[j-1][i],best[j-1][stramos[j-1][i]]);
		}
	}
}

inline int Stramos(int nod,int nr)
{
	if(nod==0)
		return 0;
	if(nr==0)
		return nod;
	nod=stramos[put[nr]][nod];
	nr-=(1<<put[nr]);
	return Stramos(nod,nr);
}

inline int Query(int nod,int nr)
{
	if(nod==0 || nr==0)
		return 0;
	int rez=best[put[nr]][nod];
	nod=stramos[put[nr]][nod];
	nr-=(1<<put[nr]);
	return max(rez,Query(nod,nr));
}

inline int CautareBinara(int x,int y)
{
	int st,dr,mij,rez=1;;
	st=1;
	dr=min(niv[x],niv[y]);
	while(st<=dr)
	{
		mij=(st+dr)/2;
		if(Stramos(x,niv[x]-mij)==Stramos(y,niv[y]-mij))
		{
			rez=max(rez,mij);
			st=mij+1;
		}
		else
			dr=mij-1;
	}
	return rez;
}

inline void Rezolvare()
{
	int x,y,lvl;
	freopen("radiatie.out","w",stdout);
	while(K--)
	{
		scanf("%d %d",&x,&y);
		lvl=CautareBinara(x,y);
		printf("%d\n",max(Query(x,niv[x]-lvl),Query(y,niv[y]-lvl)));
	}
}

int main()
{
	Citire();
	Kruskal();
	Stramosi();
	Rezolvare();
	return 0;
}