Cod sursa(job #2770197)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 19 august 2021 20:51:17
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.52 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("radiatie.in");
ofstream fout("radiatie.out");

const int MAXN = 15005;
const int MAXM = 3e4;
vector<pair<int,int>> G[MAXN];
int depth[MAXN];

struct edge {
  int u, v, w;

  void read() {
    fin >> u >> v >> w;
  }

  bool operator < (const edge &A) const {
    return w < A.w;
  }
} edges[MAXM];

struct DSU {
  vector<int> p, r;

  DSU(int n) {
    p.resize(n + 1);
    iota(p.begin(), p.end(), 0);
    r.assign(n + 1, 1);
  }

  int get(int x) {
    if (x == p[x])
      return x;
    return p[x] = get(p[x]);
  }

  bool unite(int u, int v) {
    int x = get(u), y = get(v);
    if (x == y)
      return false;
    if (r[x] > r[y])
      swap(x, y);
    p[x] = y;
    r[y] += r[x];
    return true;
  }
};

struct lca_node {
  int prv, mx;
} ancestor[MAXN][15];

void dfs(const int &u, const int &parent) {
  for (int lift = 1; lift < 15; ++lift) {
    lca_node &p = ancestor[u][lift];
    lca_node half_ancestor = ancestor[u][lift - 1];
    p.prv = ancestor[half_ancestor.prv][lift - 1].prv;
    p.mx = max(half_ancestor.mx, ancestor[half_ancestor.prv][lift - 1].mx);
  }
  for (const pair<int,int> &v : G[u])
    if (v.first != parent) {
      depth[v.first] = depth[u] + 1;
      ancestor[v.first][0] = lca_node{u, v.second};
      dfs(v.first, u);
    }
}

void max_self(int &x, int y) {
  if (x < y)
    x = y;
}

int query_max(int u, int v) {
  if (depth[u] < depth[v])
    swap(u, v);
  int ans = 0;
  for (int lift = 14; lift >= 0; --lift)
    if (depth[u] - (1 << lift) >= depth[v]) {
      lca_node node = ancestor[u][lift];
      max_self(ans, node.mx);
      u = node.prv;
    }
  if (u == v)
    return ans;
  for (int lift = 14; lift >= 0; --lift) {
    lca_node x = ancestor[u][lift], y = ancestor[v][lift];
    if (x.prv != y.prv) {
      max_self(ans, x.mx), max_self(ans, y.mx);
      u = x.prv, v = y.prv;
    }
  }
  return max({ans, ancestor[u][0].mx, ancestor[v][0].mx});
}

int main() {
  int n, m, q;
  fin >> n >> m >> q;
  for (int i = 0; i < m; ++i)
    edges[i].read();
  sort(edges, edges + m);
  DSU tree(n);
  for (int i = 0; i < m; ++i) {
    int u = edges[i].u, v = edges[i].v, w = edges[i].w;
    if (tree.unite(u, v)) {
      G[u].emplace_back(v, w);
      G[v].emplace_back(u, w);
    }
  }
  dfs(1, 0);
  for (int i = 0; i < q; ++i) {
    int u, v;
    fin >> u >> v;
    fout << query_max(u, v) << '\n';
  }
  fin.close();
  fout.close();
  return 0;
}