Pagini recente » Cod sursa (job #67601) | Cod sursa (job #2392296) | Cod sursa (job #46639) | Cod sursa (job #2770726) | Cod sursa (job #2864792)
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");
struct Edge
{
int a, b;
int c;
};
struct Node
{
int destination;
int cost;
};
bool cmp(const Edge& a, const Edge& b)
{
return a.c < b.c;
}
int n, m, k;
vector <Edge> edges;
vector <Node> graph[15005];
int fathers[15005];
int level[100005];
Node ancestors[20][100005];
bool visited[15005];
int logE;
int FindRoot(int node)
{
if (node == fathers[node])
{
return node;
}
return fathers[node] = FindRoot(fathers[node]);
}
void Union(int a, int b)
{
a = FindRoot(a);
b = FindRoot(b);
if (rand() % 2 == 1)
{
fathers[b] = a;
}
else
{
fathers[a] = b;
}
}
int LCA(int a, int b)
{
if (a == b)
{
return 0;
}
int maxVal = 0;
for (int e = logE; e >= 0; e--)
{
maxVal = max(maxVal, ancestors[e][a].cost);
maxVal = max(maxVal, ancestors[e][b].cost);
if (ancestors[e][a].destination != ancestors[e][b].destination)
{
a = ancestors[e][a].destination;
b = ancestors[e][b].destination;
}
}
return maxVal;
}
int Equalize(int &a, int &b)
{
int e = logE;
int maxVal = 0;
while (level[b] - level[a] > 0)
{
//maxVal = max(maxVal, ancestors[e][a].cost);
int dif = level[b] - level[a];
if ((1 << e) <= dif)
{
maxVal = max(maxVal, ancestors[e][b].cost);
b = ancestors[e][b].destination;
}
e--;
}
return maxVal;
}
int DFS(int node, int lvl)
{
visited[node] = true;
level[node] = lvl;
int currMax = lvl;
//cout << node << ' ';
for (Node x : graph[node])
{
if (visited[x.destination])
{
continue;
}
currMax = max(DFS(x.destination, lvl + 1), currMax);
ancestors[0][x.destination] = {node, x.cost};
fathers[x.destination] = node;
}
return currMax;
}
int main()
{
fin >> n >> m >> k;
for (int i = 0; i < m; i++)
{
int a, b, c;
fin >> a >> b >> c;
Edge newEdge = {a, b, c};
edges.push_back(newEdge);
}
sort(edges.begin(), edges.end(), cmp);
for (int i = 1; i <= n; i++)
{
fathers[i] = i;
}
for (Edge edge : edges)
{
if (FindRoot(edge.a) == FindRoot(edge.b))
{
continue;
}
//cout << edge.c << ' ';
Union(edge.a, edge.b);
Node newNode = {edge.b, edge.c};
graph[edge.a].push_back(newNode);
newNode = {edge.a, edge.c};
graph[edge.b].push_back(newNode);
}
logE = (int)log2(DFS(1, 1));
for (int e = 1; e <= logE; e++)
{
for (int i = 1; i <= n; i++)
{
ancestors[e][i].destination = ancestors[e - 1][ancestors[e - 1][i].destination].destination;
ancestors[e][i].cost = max(ancestors[e - 1][i].cost, ancestors[e - 1][ancestors[e - 1][i].destination].cost);
}
}
for (int i = 0; i < k; i++)
{
int a, b;
fin >> a >> b;
int maxVal;
if (level[a] > level[b])
{
maxVal = Equalize(b, a);
}
else
{
maxVal = Equalize(a, b);
}
fout << max(maxVal, LCA(a, b)) << '\n';
}
}