Cod sursa(job #3217976)

Utilizator Traian_7109Traian Mihai Danciu Traian_7109 Data 25 martie 2024 14:57:22
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <bits/stdc++.h>

using namespace std;

const int mmax = 30000;
struct Edge {
  int u, v, w;
} edges[5 + mmax];
inline bool cmp(Edge a, Edge b) {
  return a.w < b.w;
}

const int nmax = 15000;
int par[5 + nmax], card[5 + nmax];
int root(int u) {
  if (u == par[u])
    return u;
  return par[u] = root(par[u]);
}
void unite(int u, int v) {
  u = root(u);
  v = root(v);
  if (card[u] < card[v])
    swap(u, v);
  card[u] += card[v];
  par[v] = u;
}

vector<pair<int, int>> g[5 + nmax];
int lg2[5 + nmax];
const int LOG = 15;
int anc[5 + LOG][5 + nmax], maxdrum[5 + LOG][5 + nmax];
int level[5 + nmax], tin[5 + nmax], tout[5 + nmax], ptr;
 
void dfs(int node, int parent, int depth, int cost) {
  anc[0][node] = parent;
  maxdrum[0][node] = cost;
  for (int i = 1; i < LOG; i++) {
    anc[i][node] = anc[i - 1][anc[i - 1][node]];
    maxdrum[i][node] = max(maxdrum[i - 1][node], maxdrum[i - 1][anc[i - 1][node]]);
  }
  level[node] = depth;
  tin[node] = ++ptr;
  for (pair<int, int> edge : g[node]) {
    int son = edge.first, cost = edge.second;
    if (son != parent)
      dfs(son, node, depth + 1, cost);
  }
  tout[node] = ++ptr;
}

int kthanc(int u, int k) {
  for (int bit = 0; bit < LOG; bit++)
    if (k & (1 << bit))
      u = anc[bit][u];
  return u;
}

inline int isanc(int u, int v) {
  return tin[u] <= tin[v] && tout[v] <= tout[u];
}

int getlca(int u, int v) {
  if (isanc(u, v))
    return u;
  for (int bit = LOG - 1; bit >= 0; bit--)
    if (level[u] >= (1 << bit) && !isanc(anc[bit][u], v))
      u = anc[bit][u];
  return anc[0][u];
}

int main() {
  ifstream fin("radiatie.in");
  ofstream fout("radiatie.out");
  int n, m, k;
  fin >> n >> m >> k;
  for (int i = 1; i <= m; i++)
    fin >> edges[i].u >> edges[i].v >> edges[i].w;
  sort(edges + 1, edges + m + 1, cmp);
  for (int i = 1; i <= n; i++) {
    par[i] = i;
    card[i] = 1;
  }
  for (int i = 2; i <= n; i++)
    lg2[i] = 1 + lg2[i >> 1];
  for (int i = 1; i <= m; i++)
    if (root(edges[i].u) != root(edges[i].v)) {
      unite(edges[i].u, edges[i].v);
      g[edges[i].u].emplace_back(edges[i].v, edges[i].w);
      g[edges[i].v].emplace_back(edges[i].u, edges[i].w);
    }
  dfs(1, 0, 0, 0);
  for (int i = 1; i <= k; i++) {
    int u, v;
    fin >> u >> v;
    int lca = getlca(u, v), lg, ans = 0;
    if (u != lca) {
      lg = lg2[level[u] - level[lca]];
      ans = max(ans, max(maxdrum[lg][kthanc(u, level[u] - level[lca] - (1 << lg))], maxdrum[lg][u]));
    }
    if (v != lca) {
      lg = lg2[level[v] - level[lca]];
      ans = max(ans, max(maxdrum[lg][kthanc(v, level[v] - level[lca] - (1 << lg))], maxdrum[lg][v]));
    }
    fout << ans << '\n';
  }
  return 0;
}