Cod sursa(job #3327441)

Utilizator RaresHRares Hanganu RaresH Data 3 decembrie 2025 21:51:32
Problema Radiatie Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

FILE* fin;
FILE* fout;

const int MAX_N = 10'000;
const int MAX_M = 30'000;
const int LOG = 14;

struct Edge {
  int u, v, w;
};

struct EdgeAdj {
  int v, w;
};

struct Dsu {
  int p[MAX_N], sz[MAX_N];

  void init(int n) {
    for(int i = 0; i < n; i++) {
      p[i] = i;
      sz[i] = 1;
    }
  }

  int find(int a) {
    if(p[a] == a) {
      return a;
    }
    return p[a] = find(p[a]);
  }

  void join(int a, int b) {
    int pa = find(a);
    int pb = find(b);
    if(pa != pb) {
      if(sz[pa] > sz[pb]) {
        std::swap(pa, pb);
      }
      p[pa] = pb;
      sz[pb] += sz[pa];
    }
  }

  bool are_joined(int a, int b) {
    return find(a) == find(b);
  }
};

std::vector<EdgeAdj> adj[MAX_N];
Edge edges[MAX_M];
int tin[MAX_N], tout[MAX_N];
int up[LOG][MAX_N];
int maxw[LOG][MAX_N];
Dsu dsu;

bool is_ancestor(int u, int v) {
  if(u == -1) {
    return true;
  }
  return tin[u] <= tin[v] && tout[u] >= tout[v];
}

int get_lca(int u, int v) {
  if(is_ancestor(u, v)) {
    return u;
  }
  for(int i = LOG - 1; i >= 0; i--) {
    if(!is_ancestor(up[i][u], v)) {
      u = up[i][u];
    }
  }
  return up[0][u];
}

void dfs(int u, int prev = -1, int prevw = 0) {
  static int time = 0;
  tin[u] = time++;
  up[0][u] = prev;
  maxw[0][u] = prevw;
  for(auto [v, w] : adj[u]) {
    if(v != prev) {
      dfs(v, u, w);
    }
  }
  tout[u] = time++;
}

int get_max_w(int u, int v) {
  if(u == v) {
    return 0;
  }
  int ret = 0;
  for(int i = LOG - 1; i >= 0; i--) {
    if(!is_ancestor(up[i][v], u)) {
      ret = std::max(ret, maxw[i][v]);
      v = up[i][v];
    }
  }
  return std::max(ret, maxw[0][v]);
}

int main() {
  fin = fopen("radiatie.in", "r");
  fout = fopen("radiatie.out", "w");

  int n, m, k;
  fscanf(fin, "%d%d%d", &n, &m, &k);

  for(int i = 0; i < m; i++) {
    int u, v, w;
    fscanf(fin, "%d%d%d", &u, &v, &w);
    u--;
    v--;
    edges[i] = {u, v, w};
  }

  std::sort(edges, edges + m, [](const Edge& a, const Edge& b) {
    return a.w < b.w;
  });

  dsu.init(n);
  for(int i = 0; i < m; i++) {
    if(!dsu.are_joined(edges[i].u, edges[i].v)) {
      adj[edges[i].u].push_back({edges[i].v, edges[i].w});
      adj[edges[i].v].push_back({edges[i].u, edges[i].w});
      dsu.join(edges[i].u, edges[i].v);
    }
  }

  dfs(0);

  for(int i = 1; i < LOG; i++) {
    for(int j = 0; j < n; j++) {
      up[i][j] = up[i - 1][up[i - 1][j]];
      maxw[i][j] = std::max(maxw[i - 1][j], maxw[i - 1][up[i - 1][j]]);
    }
  }

  for(int i = 0; i < k; i++) {
    int u, v;
    fscanf(fin, "%d%d", &u, &v);
    u--;
    v--;
    int lca = get_lca(u, v);
    int ans = std::max(get_max_w(lca, u), get_max_w(lca, v));
    fprintf(fout, "%d\n", ans);
  }

  fclose(fin);
  fclose(fout);

  return 0;
}