Cod sursa(job #2437370)

Utilizator AlexPop28Pop Alex-Nicolae AlexPop28 Data 9 iulie 2019 13:39:03
Problema Radiatie Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <bits/stdc++.h>

using namespace std;

struct DSU {
  int n;
  vector<int> dad, rnk;
  DSU(int n_) : n(n_), dad(n, -1), rnk(n, 1) {}
  int Find(int x) {
    if (dad[x] == -1) return x;
    return dad[x] = Find(dad[x]);
  }
  void Union(int x, int y) {
    x = Find(x), y = Find(y);
    if (rnk[x] > rnk[y]) swap(x, y);
    dad[x] = y;
    rnk[y] += rnk[x] == rnk[y]; 
  }
};

int main() {
  ifstream cin("radiatie.in");
  ofstream cout("radiatie.out");

  int n, m, k; cin >> n >> m >> k;
  vector<tuple<int, int, int>> edges(m);
  for (int i = 0; i < m; ++i) {
    int a, b, c; cin >> a >> b >> c; --a, --b;
    edges[i] = make_tuple(c, a, b);
  } 
  sort(edges.begin(), edges.end());
  DSU g(n);
  vector<vector<pair<int, int>>> adj(n);
  for (auto &e : edges) {
    int c, a, b; tie(c, a, b) = e;
    if (g.Find(a) == g.Find(b)) {
      continue;
    }
    adj[a].emplace_back(b, c);
    adj[b].emplace_back(a, c);
  }
  int logn = 1;
  while ((1 << logn) <= n) ++logn;
  vector<vector<pair<int, int>>> anc(n, vector<pair<int, int>>(logn));
  vector<bool> vis(n);
  vector<int> lvl(n);
  function<void(int)> DFS = [&](int node) {
    vis[node] = true;
    for (int bit = 1; bit < logn; ++bit) {
      if (anc[node][bit - 1].first == -1) break;
      anc[node][bit] = anc[anc[node][bit - 1].first][bit - 1]; 
      anc[node][bit].second = max(anc[node][bit].second, anc[node][bit - 1].second);
    }
    for (auto &p : adj[node]) {
      int x, cost; tie(x, cost) = p;
      if (vis[x]) continue;
      anc[x][0] = {node, cost};
      lvl[x] = lvl[node] + 1;
      DFS(x);
    }
  };
  for (int i = 0; i < n; ++i) {
    if (!vis[i]) {
      anc[i][0] = {-1, 0};
      DFS(i);
    }
  }
  auto Solve = [&](int a, int b) {
    if (lvl[a] > lvl[b]) swap(a, b);
    int diff = lvl[b] - lvl[a];
    int ans = 0;
    for (int bit = 0; diff > 0; ++bit) {
      if (diff & (1 << bit)) {
        diff ^= (1 << bit);
        ans = max(ans, anc[b][bit].second);
        b = anc[b][bit].first;  
      }
    }
    if (a == b) return ans;
    for (int bit = logn - 1; bit >= 0; --bit) {
      if (anc[a][bit].first != anc[b][bit].first) {
        ans = max({ans, anc[a][bit].second, anc[b][bit].second});
        a = anc[a][bit].first;
        b = anc[b][bit].first;
      }
    }
    assert(anc[a][0].first == anc[b][0].first && a != b);
    ans = max({ans, anc[a][0].second, anc[b][0].second});
    return ans;
  };
  
  while (k--) {
    int a, b; cin >> a >> b; --a, --b;
    cout << Solve(a, b) << '\n';
  }
}