Cod sursa(job #2927041)

Utilizator YusyBossFares Yusuf YusyBoss Data 19 octombrie 2022 11:04:16
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.1 kb
#include <bits/stdc++.h>
#define NMAX 15000
#define MMAX 30000
#define LOGMAX 14

using namespace std;

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

struct strmuchie{
  int node1, node2, cost;
};

struct strson {
  int node, cost;
};

int vlog2[NMAX + 1];
int vlevel[NMAX + 1];
strson vstram[NMAX + 1][LOGMAX + 1];
int vtata[NMAX + 1];
bool is_visited[NMAX + 1];
strmuchie vmuchie[MMAX + 1];
vector <strson> vsons[NMAX + 1];

bool cmp(strmuchie A, strmuchie B) {
  return A.cost < B.cost;
}

int get_tata(int node) {
  if (node == vtata[node])
    return node;

  vtata[node] = get_tata(vtata[node]);
  return vtata[node];
}

bool u(int node1, int node2) {
  int tata1 = get_tata(node1);
  int tata2 = get_tata(node2);

  vtata[tata1] = tata2;
  return !(tata1 == tata2);
}

void prec_log2() {
  int i;

  for (i = 2; i <= NMAX; i++)
    vlog2[i] = vlog2[i / 2] + 1;
}

strson go_up(int node, int nlevel) {
  if (nlevel == 0)
    return {node, -1};
  auto crt = go_up(vstram[node][vlog2[nlevel]].node, nlevel - (1 << vlog2[nlevel]));
  return {crt.node, max(crt.cost, vstram[node][vlog2[nlevel]].cost)};
}

void dfs(int node, int tata, int level, int cost) {
  int i, nsons;

  is_visited[node] = true;
  vstram[node][0] = {tata, cost};
  for (i = 1; level - (1 << i) >= 1; i++) {
    vstram[node][i].node = vstram[vstram[node][i - 1].node][i - 1].node;
    vstram[node][i].cost = max(vstram[node][i - 1].cost, vstram[vstram[node][i - 1].node][i - 1].cost);
  }
  vlevel[node] = level;

  nsons = vsons[node].size();
  for (i = 0; i < nsons; i++) {
    int newnode = vsons[node][i].node;
    if (!is_visited[newnode])
      dfs(newnode, node, level + 1, vsons[node][i].cost);
  }
}

int solve_query(int node1, int node2) {
  int sol, i;

  if (vlevel[node1] > vlevel[node2])
    swap(node1, node2);

  auto crt = go_up(node2, vlevel[node2] - vlevel[node1]);

  node2 = crt.node;
  sol = crt.cost;
  for (i = LOGMAX; i >= 0; i--) {
    if (vlevel[node1] - (1 << i) >= 1 && vstram[node1][i].node != vstram[node2][i].node) {
      sol = max(sol, vstram[node1][i].cost);
      sol = max(sol, vstram[node2][i].cost);
      node1 = vstram[node1][i].node;
      node2 = vstram[node2][i].node;
    }
  }

  if (node1 != node2) {
    sol = max(sol, vstram[node1][0].cost);
    sol = max(sol, vstram[node2][0].cost);
  }

  return sol;
}

int main() {
  int n, m, q, i, node1, node2;
  fin >> n >> m >> q;

  for (i = 0; i < m; i++)
    fin >> vmuchie[i].node1 >> vmuchie[i].node2 >> vmuchie[i].cost;

  for (i = 1; i <= n; i++)
    vtata[i] = i;

  sort(vmuchie, vmuchie + m, cmp);

  for (i = 0; i < m; i++) {
    if (u(vmuchie[i].node1, vmuchie[i].node2)) {
      vsons[vmuchie[i].node1].push_back({vmuchie[i].node2, vmuchie[i].cost});
      vsons[vmuchie[i].node2].push_back({vmuchie[i].node1, vmuchie[i].cost});
    }
  }

  prec_log2();
  for (i = 1; i <= n; i++) {
    if (!is_visited[i])
      dfs(i, 0, 1, -1);
  }

  while (q--) {
    fin >> node1 >> node2;
    fout << solve_query(node1, node2) << "\n";
  }
  return 0;
}