Pagini recente » Cod sursa (job #267391) | Cod sursa (job #3262922) | Cod sursa (job #1542454) | Cod sursa (job #1140710) | Cod sursa (job #2656587)
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
ifstream fin ("radiatie.in");
ofstream fout ("radiatie.out");
int tt[15001], rg[15001], lev[15001];
int ttt[14][15001], b[14][15001];
struct latura
{
int a, b, c;
}v[30001];
struct nod
{
int info, cost;
nod * urm;
}*vecin[30001];
nod * prim[30001];
int comparare(latura x, latura y)
{
return x.c<y.c;
}
int find(int x)
{
int r, y=x;
while(tt[y]!=y)
{
y=tt[y];
}
r=y;
//aplic compresia drumurilor
while(tt[x]!=x)
{
y=tt[x];
tt[x]=r;
x=y;
}
return r;
}
void unite(int x, int y, int nr, int cost)
{
if(rg[x]<rg[y])
{
tt[x]=y;
//il adaug pe v[i].a la fiii lui v[i].b
nod * aux = new nod;
aux->info=v[nr].a;
aux->cost=cost;
aux->urm=NULL;
if(prim[ v[nr].b ]==NULL)
{
prim[ v[nr].b ]=aux;
vecin[ v[nr].b ]=aux;
}
else
{
vecin[ v[nr].b ]->urm=aux;
vecin[ v[nr].b ]=aux;
}
}
else
{
tt[y]=x;
//il adaug pe v[i].b la fiii lui v[i].a
nod * aux = new nod;
aux->info=v[nr].b;
aux->cost=cost;
aux->urm=NULL;
if(prim[ v[nr].a ]==NULL)
{
prim[ v[nr].a ]=aux;
vecin[ v[nr].a ]=aux;
}
else
{
vecin[ v[nr].a ]->urm=aux;
vecin[ v[nr].a ]=aux;
}
}
if(rg[x]==rg[y])
{
rg[x]++;
}
}
void DFS(int x, int lvl)
{
lev[x]=lvl;
nod * t=prim[x];
while(t!=NULL)
{
ttt[0][t->info]=x;
b[0][t->info]=t->cost;
DFS(t->info, lvl+1);
t=t->urm;
}
}
int lca (int x, int y)
{
int i, log1, log2, rez;
if(lev[x]<lev[y])
{
swap(x, y);
}
//calculez log2 x si log2 y;
for(log1=1; (1<<log1)<x; log1++);
for(log2=1; (1<<log2)<y; log2++);
//il aduc pe x la nivelul lui y;
rez=0;
for(i=log1; i>=0; i--)
{
if(lev[x]-(1<<i) >= lev[y])
{
rez=max(rez, b[i][x]);
x=ttt[i][x];
}
}
if(x==y) return rez;
for(i=log2; i>=0; i--)
{
if(ttt[i][x] && ttt[i][x]!=ttt[i][y])
{
rez=max(rez, b[i][x]);
x=ttt[i][x];
rez=max(rez, b[i][y]);
y=ttt[i][y];
}
}
return max(b[0][y], max(rez, b[0][x]));
}
int main()
{
int n, m, nrc, k, i, j, logn;
fin>>n>>m>>nrc;
for(i=1; i<=m; i++)
{
fin>>v[i].a>>v[i].b>>v[i].c;
}
sort(v+1, v+m+1, comparare);
for(i=1; i<=n; i++)
{
tt[i]=i;
}
k=0;
i=1;
while(k<n-1)
{
int aux1=find(v[i].a);
int aux2=find(v[i].b);
if(aux1!=aux2)
{
//cout<<"Unesc "<<aux1<<" cu "<<aux2<<"\n";
//cout<<"rg["<<aux1<<"]= "<<rg[aux1]<<"\nrg["<<aux2<<"]= "<<rg[aux2]<<"\n";
k++;
unite(aux1, aux2, i, v[i].c);
//cout<<"rg["<<aux1<<"]= "<<rg[aux1]<<"\nrg["<<aux2<<"]= "<<rg[aux2]<<"\n\n";
}
i++;
}
//caut radacina, adica numarul cu rg maxim si aplic DFS ca sa marchez nivelele
int max1=0, rad;
for(i=1; i<=n; i++)
{
if(rg[i]>max1)
{
max1=rg[i];
rad=i;
}
}
DFS(rad, 0);
//cout<<"rad= "<<rad<<"\n";
/*for(i=1; i<=n; i++)
{
cout<<"lev["<<i<<"]= "<<lev[i]<<"\n";
}cout<<"\n";*/
//afisez pentru fiecare vecinii sai:
/*for(i=1; i<=n; i++)
{
cout<<i<<": ";
nod * t = prim[i];
while(t!=NULL)
{
cout<<t->info<<' ';
t=t->urm;
}
cout<<"\n";
}
cout<<"\n";*/
for(logn=1; (1<<logn)<n; logn++);
for(i=1; i<=logn; i++)
{
for(j=1; j<=n; j++)
{
ttt[i][j]=ttt[i-1][ ttt[i-1][j] ];
b[i][j]=max(b[i-1][j], b[i-1][ ttt[i-1][j] ]);
}
}
int x, y;
for(i=1; i<=nrc; i++)
{
fin>>x>>y;
fout<<lca(x, y)<<"\n";
}
}