Cod sursa(job #388737)

Utilizator AndreyPAndrei Poenaru AndreyP Data 30 ianuarie 2010 20:09:04
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.11 kb
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
#define N 15010
#define M 30010
#define fs first
#define sc second
#define mp make_pair
#define pii pair<int,int>
#define pb push_back
struct Muchie
{
	int x,y,z;
};
int n,m,k;
Muchie v[M];
int ind[M];
int t[N],deg[N];
vector< pii > a[N];
pii strm[15][N];
int b[17][3*N];
int lo[3*N];
int poz[N];
int niv[N];
int ord[N];
int indice;
inline void citire()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0; i<m; ++i)
	{
		scanf("%d%d%d",&v[i].x,&v[i].y,&v[i].z);
		ind[i]=i;
	}
}
bool compar(const int &x,const int &y)
{
	if(v[x].z<v[y].z)
		return true;
	return false;
}
inline int find(int x)
{
	int r=x;
	for(; t[r]!=r; r=t[r])
		;
	int aux;
	while(x!=r)
	{
		aux=t[x];
		t[x]=r;
		x=aux;
	}
	return r;
}
inline void unire(int x,int y)
{
	x=find(x);
	y=find(y);
	if(deg[x]<deg[y])
		t[x]=y;
	else
		t[y]=x;
	if(deg[x]==deg[y])
		++deg[x];
}
inline void kruskal()
{
	sort(ind,ind+m,compar);
        for(int i=1; i<=n; ++i)
	{
		t[i]=i;
		deg[i]=1;
	}
	int n1=n-1;
	int x,y;
        for(int i=0; i<m && n1>0; ++i)
	{
        	x=v[ind[i]].x;
		y=v[ind[i]].y;
		if(find(x)==find(y))
			continue;
		--n1;
		a[x].pb(mp(y,v[ind[i]].z));
		a[y].pb(mp(x,v[ind[i]].z));
                unire(x,y);
	}
}
void dfs(int nod,int fn,int h)
{
        poz[nod]=++indice;
	ord[++ord[0]]=nod;
        niv[nod]=h;
	b[0][indice]=h;
	for(size_t i=0,lim=a[nod].size(); i<lim; ++i)
	{
        	if(a[nod][i].fs==fn)
			continue;
		strm[0][a[nod][i].fs].fs=a[nod][i].sc;
		strm[0][a[nod][i].fs].sc=nod;
		dfs(a[nod][i].fs,nod,h+1);
		++indice;
		b[0][indice]=h;
	}
}
inline int minim(int x,int y)
{
	if(x<y)
		return x;
	return y;
}
inline int maxim(int x,int y)
{
	if(x>y)
		return x;
	return y;
}
inline void rmq()
{
	lo[2]=1;
	for(int i=3; i<=indice; ++i)
		lo[i]=lo[i>>1]+1;

	int dim,dim1;
	for(int i=1; i<=lo[indice]; ++i)
	{
		dim=1<<i;
		dim1=dim>>1;
                for(int j=1; j+dim<=indice; ++j)
			b[i][j]=minim(b[i-1][j],b[i-1][j+dim1]);
	}
}
bool compar1(const int &x,const int &y)
{
	if(niv[x]>niv[y])
		return true;
	return false;
}
inline void stramosi()
{
	sort(ord+1,ord+ord[0]+1,compar1);
        for(int i=1; i<=lo[niv[ord[1]]]; ++i)
	{
        	for(int j=1; j<=ord[0] && i<=lo[niv[ord[j]]]; ++j)
		{
                	strm[i][ord[j]].fs=maxim(strm[i-1][ord[j]].fs,strm[i-1][strm[i-1][ord[j]].sc].fs);
			strm[i][ord[j]].sc=strm[i-1][strm[i-1][ord[j]].sc].sc;
		}
	}
}
inline int lca(int x,int y)
{
	if(poz[x]>poz[y])
        	swap(x,y);
	int cat=lo[poz[y]-poz[x]];
	return minim(b[cat][poz[x]],b[cat][poz[y]-(1<<cat)+1]);
}
inline int spune(int nod,int cat)
{
	int r=0;
	for(int i=lo[cat]; i>=0; --i)
	{
        	if((cat&(1<<i))==0)
			continue;
		if(r<strm[i][nod].fs)
			r=strm[i][nod].fs;
		nod=strm[i][nod].sc;
	}
	return r;
}
inline void afla()
{
	int x,y;
	scanf("%d%d",&x,&y);
        if(x==y)
	{
		printf("0\n");
		return;
	}
	int cat=lca(x,y);
	printf("%d\n",maxim(spune(x,niv[x]-cat),spune(y,niv[y]-cat)));
}
int main()
{
	freopen("radiatie.in","r",stdin);
	freopen("radiatie.out","w",stdout);
	citire();
        kruskal();
	dfs(1,0,0);
	rmq();
	stramosi();
        for(int i=0; i<k; ++i)
		afla();
	return 0;
}