Pagini recente » Cod sursa (job #473569) | Cod sursa (job #1400560) | Cod sursa (job #933239) | Cod sursa (job #147785) | Cod sursa (job #1640650)
#include <fstream>
#include <vector>
#include <algorithm>
constexpr int kMaxN = 15000;
constexpr int kMaxRmqLevels = 17;
struct Edge
{
int x, y, weight;
Edge(int arg_x, int arg_y, int arg_weight) :
x(arg_x), y(arg_y), weight(arg_weight)
{
}
bool operator<(const Edge& edge) const
{
return weight < edge.weight;
}
};
Edge makeEdge(int x, int y, int weight)
{
Edge temp(x, y, weight);
return temp;
}
int n, m, k;
std::vector<Edge> v_edges;
std::vector<std::pair<int, int> > mst[kMaxN];
std::vector<int> rmq[kMaxRmqLevels]; //contains the edge from the i-th to (i+1)-th euler positions
std::vector<int> euler_positions[kMaxN];
int queryRmq(int a, int b)
{
int j = 0;
int result = 0;
while(a <= b) {
if(a%2 == 1) {
result = std::max(result, rmq[0][a]);
++a;
}
if(b >= a && b%2 == 0) {
result = std::max(result, rmq[0][b]);
--b;
}
if(b < a) break;
a/=2; b/=2;
++j;
}
return result;
}
void buildRmq()
{
int j = 0;
while(true) {
++j;
for(int i = 1; i*2 <= rmq[j-1].size(); ++i) {
rmq[j].push_back(std::max(rmq[j-1][i*2-2], rmq[j-1][i*2-1]));
}
if(rmq[j].size() < 2) return;
}
}
//Dfs for mst to compute euler positions and the rmq
void dfs(int x, int parent)
{
euler_positions[x].push_back(rmq[0].size());
for(auto& edge : mst[x]) {
if(edge.first != parent) {
rmq[0].push_back(edge.second);
dfs(edge.first, x);
rmq[0].push_back(edge.second);
euler_positions[rmq[0].size()];
}
}
}
//Kruskal's algorithm
void computeMst()
{
int *v = new int[n+1];
std::sort(v_edges.begin(), v_edges.end());
for(int i = 1; i <= n; ++i) v[i] = 0;
for(auto& edge : v_edges) {
int x = edge.x;
int y = edge.y;
int a = x, b = y;
while(v[a] != 0) a = v[a];
while(v[b] != 0) b = v[b];
if(a != b) {
mst[x].push_back(std::make_pair(y, edge.weight));
mst[y].push_back(std::make_pair(x, edge.weight));
v[a] = b;
}
int aux;
while(x != a) {
aux = v[x];
v[x] = a;
x = aux;
}
while(y != b) {
aux = v[y];
v[y] = b;
y = aux;
}
}
}
int query(int x, int y)
{
if(euler_positions[x].back() < euler_positions[y].front())
return queryRmq(euler_positions[x].back(), euler_positions[y].front());
else if(euler_positions[y].back() < euler_positions[x].front())
return queryRmq(euler_positions[y].back(), euler_positions[x].front());
else {
if(euler_positions[x].front() < euler_positions[y].front()) {
for(auto it = euler_positions[x].begin(); it != euler_positions[x].end(); ++it) {
if(*it > euler_positions[y].front()) return queryRmq(*(it-1), euler_positions[y].front());
}
}
else {
for(auto it = euler_positions[y].begin(); it != euler_positions[y].end(); ++it) {
if(*it > euler_positions[y].front()) return queryRmq(*(it-1), euler_positions[x].front());
}
}
}
return 0;
}
int main()
{
std::ifstream in("radiatie.in");
std::ofstream out("radiatie.out");
in>>n>>m>>k;
for(int x, y, w, i = 1; i <= m; ++i) {
in>>x>>y>>w;
v_edges.push_back(makeEdge(x, y, w));
}
computeMst();
dfs(1, 0);
buildRmq();
for(int x, y, i = 1; i <= k; ++i) {
in>>x>>y;
out<<query(x, y)<<'\n';
}
}