Pagini recente » Cod sursa (job #1517132) | Cod sursa (job #844134) | Cod sursa (job #1202167) | Cod sursa (job #2512029) | Cod sursa (job #1097040)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");
int N, M, nr_question;
int K, first_nod, log_N;
int X[30002], Y[30002], C[30002], pos[30002], C_stramos[15001];
int T[30002], R[30002];
int LVL[30002], EULER[30002], logaritm[30002], First[15001];
int RMQ[60001][20];
int stramos[20][15001], max_muchie[20][15001];
vector<pair<int, int> > V[15001];
bool used[15001], used_stramos[15001];
bool cmp(int a, int b)
{
return (C[a] < C[b]);
}
int find(int x)
{
int rad, aux;
for (rad = x; T[rad] != rad; rad = T[rad]);
while (T[rad] != rad)
{
aux = T[x];
T[x] = rad;
x = aux;
}
return rad;
}
void unite(int x, int y)
{
if (R[x] > R[y]) T[y] = x;
else T[x] = y;
if (R[x] == R[y]) ++R[y];
}
void apm()
{
sort(pos + 1, pos + M + 1, cmp);
for (int i = 1; i <= N; ++i)
{
T[i] = i;
R[i] = 1;
}
for (int i = 1; i <= M; ++i)
{
int nr1 = find(X[pos[i]]);
int nr2 = find(Y[pos[i]]);
if (nr1 != nr2)
{
unite(nr1, nr2);
if (!first_nod) first_nod = X[pos[i]];
V[X[pos[i]]].push_back(make_pair(Y[pos[i]], C[pos[i]]));
V[Y[pos[i]]].push_back(make_pair(X[pos[i]], C[pos[i]]));
}
}
}
void dfs(int nod, int nivel)
{
used[nod] = true;
EULER[++K] = nod; //nodul actual este adaugat in reprezentarea Euler a arborelui
LVL[K] = nivel; //se retine nivelul fiecarei pozitii din reprezentarea Euler a arborelui
First[nod] = K; //se retine prima aparitie a fiecarui nod in reprezentarea Euler
for (vector<pair<int, int> >::iterator it = V[nod].begin(); it != V[nod].end(); ++it)
{
if (!used[it->first])
{
stramos[0][it->first] = nod;
max_muchie[0][it->first] = it->second;
dfs(it->first, nivel + 1);
EULER[++K] = nod;
LVL[K] = nivel;
}
}
}
void rmq()
{
//in RMQ[i][j] va fi nodul de nivel minim dintre pozitiile (j, j + 2 ^ (i - 1)) din reprezentarea Euler a arborelui
logaritm[1] = 0;
for (int i = 2; i <= K; ++i)
logaritm[i] = logaritm[i >> 1] + 1;
for (int i = 1; i <= K; ++i)
RMQ[i][0] = i;
for (int j = 1; (1 << j) <= K; ++j)
for (int i = 1; i + (1 << (j - 1)) <= K; ++i)
{
int p = 1 << (j - 1);
if (LVL[RMQ[i][j - 1]] <= LVL[RMQ[i + p][j - 1]]) RMQ[i][j] = RMQ[i][j - 1];
else RMQ[i][j] = RMQ[i + p][j - 1];
}
}
int lca(int nod1, int nod2)
{
//LCA-ul nodurilor nod1 si nod2 va fi nodul cu nivel minim din secventa (First[nod1], First[nod2]) din reprezentarea Euler
int sol;
int start = First[nod1];
int finish = First[nod2];
if (start > finish) swap(start, finish);
int dif = finish - start + 1;
int l = logaritm[dif];
if (LVL[RMQ[start][l]] <= LVL[RMQ[finish - (1 << l) + 1][l]]) sol = RMQ[start][l];
else sol = RMQ[finish - (1 << l) + 1][l];
return EULER[sol];
}
void idee_stramosi()
{
for (int k = 1; k <= log_N; ++k)
for (int i = 1; i <= N; ++i)
{
stramos[k][i] = stramos[k - 1][stramos[k - 1][i]];
if (max_muchie[k - 1][stramos[k - 1][i]] == 0) max_muchie[k][i] = 0;
else max_muchie[k][i] = max(max_muchie[k - 1][i], max_muchie[k - 1][stramos[k - 1][i]]);
}
}
int find_stramos(int nod_c, int nod)
{
int nod_stramos;
bool ok = true;
if (nod == 0)
{
nod_stramos = nod_c;
ok = false;
}
while(ok)
{
if (nod == 0 || nod == 1)
{
ok = false;
break;
}
int l = logaritm[nod];
nod_stramos = stramos[l][nod_c];
nod_c = stramos[l][nod_c];
nod = nod - (1 << l);
}
if (nod == 1) nod_stramos = stramos[0][nod_c];
return nod_stramos;
}
int main()
{
fin >> N >> M >> nr_question;
for (int i = 1; i <= M; ++i)
{
fin >> X[i] >> Y[i] >> C[i];
pos[i] = i;
}
log_N = log2(N);
apm();
dfs(first_nod, 1);
rmq();
idee_stramosi();
for (int i = 1, nod1, nod2; i <= nr_question; ++i)
{
int sol1, sol2, l, nr_stramos, dif;
fin >> nod1 >> nod2;
int stramos = lca(nod1, nod2);
dif = LVL[First[nod1]] - LVL[First[stramos]];
l = logaritm[dif];
if (dif - (1 << l) < 0) nr_stramos = 0;
else nr_stramos = find_stramos(nod1, dif - (1 << l));
sol1 = max(max_muchie[l][nod1], max_muchie[l][nr_stramos]);
dif = LVL[First[nod2]] - LVL[First[stramos]];
l = logaritm[dif];
if (dif - (1 << l) < 0) nr_stramos = 0;
else nr_stramos = find_stramos(nod2, dif - (1 << l));
sol2 = max(max_muchie[l][nod2], max_muchie[l][nr_stramos]);
fout << max(sol1, sol2) << '\n';
}
fin.close();
fout.close();
return 0;
}