Pagini recente » Cod sursa (job #1154348) | Cod sursa (job #326964) | Cod sursa (job #1096874) | Cod sursa (job #2497462) | Cod sursa (job #921454)
Cod sursa(job #921454)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>
#define NM 15010
#define LM 15
#define cost first
#define node second
#define node1 second.first
#define node2 second.second
using namespace std;
ifstream f("radiatie.in");
ofstream g("radiatie.out");
typedef pair< int, pair<int, int> > PIC;
typedef pair<int, int> PI;
vector<PIC> Edges;
vector<PI> G[NM];
int N, M, K;
bool Vis[NM];
int T[NM], GR[NM];
int Father[NM], Level[NM];
int Ancestors[LM][NM];
int Max[LM][NM];
int CostM[NM];
void Read ()
{
f >> N >> M >> K;
for (int i=1; i<=M; i++)
{
int a, b, c;
f >> a >> b >> c;
Edges.push_back(make_pair(c, make_pair(a, b)));
}
}
int Root (int x)
{
int p, y;
for (p=x; p!=T[p]; p=T[p]);
for (; x!=T[x]; )
{
y=T[x];
T[x]=p;
x=T[x];
}
return p;
}
void Unite (int x, int y)
{
if (GR[x]>=GR[y])
{
GR[x]+=GR[y];
T[y]=x;
}
else
{
GR[y]+=GR[x];
T[x]=y;
}
}
void DoAPM ()
{
int i, a, b, c;
for (i=1; i<=N; i++)
{
T[i]=i;
GR[i]=1;
}
sort(Edges.begin(), Edges.end());
for (i=0; i<Edges.size(); i++)
{
a=Edges[i].node1;
b=Edges[i].node2;
c=Edges[i].cost;
if (Root(a)==Root(b)) continue;
Unite(T[a], T[b]);
G[a].push_back(make_pair(c, b));
G[b].push_back(make_pair(c, a));
}
}
void BuildTree (int Node, int Lev)
{
Level[Node]=Lev;
Vis[Node]=1;
for (vector<PI>::iterator it=G[Node].begin(); it!=G[Node].end(); ++it)
if (!Vis[it->node])
{
Father[it->node]=Node;
CostM[it->node]=it->cost;
BuildTree(it->node, Lev+1);
}
}
void BuildAncestors ()
{
int i, j;
for (i=1; i<=N; i++)
{
Ancestors[0][i]=Father[i];
Max[0][i]=CostM[i];
}
for (j=1; (1 << j)<=N; j++)
for (i=1; i<=N; i++)
{
Ancestors[j][i]=Ancestors[j-1][Ancestors[j-1][i]];
Max[j][i]=max(Max[j-1][i], Max[j-1][Ancestors[j-1][i]]);
}
}
int LCA (int a, int b)
{
int k, log1, log2;
if (Level[a]>Level[b])
swap(a, b);
for (log1=0; (1 << log1)<Level[a]; ++log1);
for (log2=0; (1 << log2)<Level[b]; ++log2);
for (k=log2; k>=0; k--)
if (Level[b]-(1 << k)>=Level[a])
b=Ancestors[k][b];
if (a==b) return a;
for (k=log1; k>=0; k--)
if (Ancestors[k][a]!=0 && Ancestors[k][a]!=Ancestors[k][b])
{
a=Ancestors[k][a];
b=Ancestors[k][b];
}
return Ancestors[0][a];
}
int UpTo (int x, int z)
{
if (Level[x]<=Level[z]) return 0;
int val=0, k, log;
for (log=0; (1 << log)<Level[x]; ++log);
for (k=log; k>=0; k--)
if (Level[x]-(1 << k)>=Level[z])
{
val=max(val, Max[k][x]);
x=Ancestors[k][x];
}
return val;
}
void Solve ()
{
int i, x, y, z;
for (i=1; i<=K; i++)
{
f >> x >> y;
z=LCA(x, y);
g << max(UpTo(x, z), UpTo(y, z)) << '\n';
}
}
int main ()
{
Read();
DoAPM();
BuildTree(1, 1);
BuildAncestors();
Solve();
f.close();
g.close();
return 0;
}