Pagini recente » Cod sursa (job #2688496) | Cod sursa (job #3139674) | Cod sursa (job #266117) | Cod sursa (job #318462) | Cod sursa (job #1399199)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream in ("radiatie.in");
ofstream out ("radiatie.out");
const int MAXN = 15000 + 10;
typedef pair <int, int> PII;
struct edge
{
int a, b, c;
} X[MAXN * 2];//graful initial
int now;//indicele pentru parcurgerea Euler
int N, M, K;//numerele din cerinta
vector <PII> Graf[MAXN];//APM-ul
int H[MAXN * 2];//parcurgerea Euler
int Lvl[MAXN * 2];//nivelul pe care apare nodul i
int First[MAXN];//prima pozitie in parcurgere pe care apare nodul i
int D[16][MAXN];//al 2^i-lea stramos al nodului j
int Smen[16][MAXN];//maximul pe drumul de la nodul j pana la al 2^i-lea stramos al sau
int RMQ[16][MAXN * 2];//nivelul maxim pe intervale din parcurgerea Euler
int Log[MAXN * 2];//logaritmul numarului i
int T[MAXN];//pt padurea de multimi disjuncte pt APM
bool Viz[MAXN];//pt parcurgerea in adancime pt constructie
PII Queries[MAXN];
struct comp
{
inline bool operator () (const edge &A, const edge &B) const
{
return A.c < B.c;
}
};
int find (int node)
{
if (T[node] == node)
return node;
T[node] = find (T[node]);
return T[node];
}
void Build_APM ()
{
sort (X + 1, X + M + 1, comp ());
int i, Tx, Ty;
int a, b, c;
for (i = 1; i <= N; i ++)
T[i] = i;
for (i = 1; i <= M; i ++){
a = X[i].a;
b = X[i].b;
c = X[i].c;
Tx = find (a);
Ty = find (b);
if (Tx != Ty){
Graf[a].push_back (make_pair (b, c));
Graf[b].push_back (make_pair (a, c));
T[Tx] = Ty;
}
}
}
void DFS (int node, int val, int father, int lev)
{
++ now;
H[now] = node;
First[node] = now;
Lvl[now] = lev;
Viz[node] = 1;
D[0][node] = father;
Smen[0][node] = val;
vector <PII> :: iterator it;
for (it = Graf[node].begin (); it != Graf[node].end (); ++ it)
if (!Viz[it -> first]){
DFS (it -> first, it -> second, node, lev + 1);
++ now;
H[now] = node;
Lvl[now] = lev;
}
}
void Build_Log ()
{
int i;
for (i = 2; i <= now; i ++)
Log[i] = Log[i / 2] + 1;
}
void Build_RMQ ()
{
int i, j, a, b;
for (i = 1; i <= now; i ++)
RMQ[0][i] = i;
for (i = 1; (1 << i) <= now; i ++)
for (j = 1; j + (1 << i) <= now; j ++){
a = RMQ[i - 1][j];
b = RMQ[i - 1][j + (1 << (i - 1))];
if (Lvl[a] <= Lvl[b])
RMQ[i][j] = a;
else
RMQ[i][j] = b;
}
}
int LCA (int x, int y)
{
x = First[x];
y = First[y];
if (x > y)
swap (x, y);
int dif = y - x + 1;
int lg = Log[dif];
int a, b;
a = RMQ[lg][x];
b = RMQ[lg][y - (1 << lg) + 1];
if (Lvl[a] <= Lvl[b])
return H[a];
else
return H[b];
}
void Build_Smen ()
{
int i, j;
for (i = 1; (1 << i) <= N; i ++)
for (j = 1; j <= N; j ++){
D[i][j] = D[i - 1][ D[i - 1][j] ];
Smen[i][j] = max (Smen[i - 1][j], Smen[i - 1][ D[i - 1][j] ]);
}
}
int Query (int x, int y)
{
int dif, i;
int Ans = -1;
dif = Lvl[First[x]] - Lvl[First[y]];
for (i = 0; (1 << i) <= dif; i ++)
if (dif & (1 << i)){
Ans = max (Ans, Smen[i][x]);
x = D[i][x];
}
return Ans;
}
int Solve (int x, int y)
{
int lca = LCA (x, y);
int a, b;
a = Query (x, lca);
b = Query (y, lca);
if (a > b)
return a;
else
return b;
}
void Read ()
{
in >> N >> M >> K;
int i;
for (i = 1; i <= M; i ++)
in >> X[i].a >> X[i].b >> X[i].c;
for (i = 1; i <= K; i ++)
in >> Queries[i].first >> Queries[i].second;
}
void Solve_Queries ()
{
int i;
for (i = 1; i <= K; i ++)
out << Solve (Queries[i].first, Queries[i].second) << "\n";
}
int main()
{
Read ();
Build_APM ();
DFS (1, 0, 0, 1);
Build_Log ();
Build_RMQ ();
Build_Smen ();
Solve_Queries ();
return 0;
}