Cod sursa(job #2900533)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 11 mai 2022 08:58:40
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <iostream>
#include <vector>
#include <algorithm>

#define MAXM 30000
#define MAXN 15000
#define MAX_LOG 14

using namespace std;

struct edge{
  int b, cost;
};

struct node{
  int lvl;
  bool visited;
  int parent, parentCost;
  vector <edge> children;
};

struct graphEdge{
  int a, b, cost;
};

bool comp(graphEdge a, graphEdge b) {
  return a.cost < b.cost;
}

graphEdge m[MAXM];
node tree[MAXN + 1];
int unions[MAXN + 1];
int firstApp[MAXN + 1];
int euler[MAXN * 2];
int eulerSize;
int logg[MAXN * 2];
int rmq[MAXN * 2][MAX_LOG];

int findFather(int x) {
  if ( unions[x] == 0 )
    return x;
  return unions[x] = findFather(unions[x]);
}

void unite(int x, int y) {
  int fatherX, fatherY;

  fatherX = findFather(x);
  fatherY = findFather(y);

  if ( fatherX != fatherY )
    unions[fatherX] = fatherY;
}

void addEdge(int a, int b, int cost) {
  tree[a].children.push_back({b, cost});
  tree[b].children.push_back({a, cost});
}

void dfs(int pos, int level) {
  tree[pos].visited = true;
  firstApp[pos] = eulerSize;
  euler[eulerSize] = pos;
  tree[pos].lvl = level;
  eulerSize++;

  for ( edge i : tree[pos].children ) {
    if ( !tree[i.b].visited ) {
      tree[i.b].parent = pos;
      tree[i.b].parentCost = i.cost;
      dfs(i.b, level + 1);
      euler[eulerSize] = pos;
      eulerSize++;
    }
  }
}

void precalcLog(int n) {
  int i;

  for ( i = 2; i <= n; i++ ) {
    logg[i] = logg[i / 2] + 1;
  }

}

void buildRmq(int n) {
  int i, i2;

  for ( i = 1; i <= n; i++ ) {
    rmq[i][0] = euler[i];
  }

  for ( i = 1; i <= logg[n]; i++ ) {
    for ( i2 = 1; i2 + (1 << i) - 1 <= n; i2++ ) {
      if ( tree[rmq[i2][i - 1]].lvl < tree[rmq[i2 + (1 << (i - 1))][i - 1]].lvl ) {
        rmq[i2][i] = rmq[i2][i - 1];
      } else {
        rmq[i2][i] = rmq[i2 + (1 << (i - 1))][i - 1];
      }
    }
  }
}

int query(int a, int b) {
  int st, dr, lenght;

  st = firstApp[a];
  dr = firstApp[b];

  if ( st > dr )
    swap(st, dr);

  lenght = dr - st + 1;
  if ( tree[rmq[st][logg[lenght]]].lvl < tree[rmq[dr - (1 << logg[lenght]) + 1][logg[lenght]]].lvl )
    return rmq[st][logg[lenght]];
  return rmq[dr - (1 << logg[lenght]) + 1][logg[lenght]];
}

int solve(int a, int b) {
  int lca, ans;

  lca = query(a, b);
  ans = 0;

  while ( tree[a].lvl > lca ) {
    ans = max(tree[a].parentCost, ans);
    a = tree[a].parent;
  }

  while ( tree[b].lvl > lca ) {
    ans = max(tree[b].parentCost, ans);
    b = tree[b].parent;
  }

  return ans;
}

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

  int n, m2, i, k, fatherA, fatherB, a, b;

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

  for ( i = 0; i < m2; i++ ) {
    fscanf(fin, "%d%d%d", &m[i].a, &m[i].b, &m[i].cost);
  }

  sort(m, m + m2, comp);

  for ( i = 0; i < m2; i++ ) {
    fatherA = findFather(m[i].a);
    fatherB = findFather(m[i].b);

    if ( fatherA != fatherB ) {
      addEdge(m[i].a, m[i].b, m[i].cost);
      unite(m[i].a, m[i].b);
    }
  }

  eulerSize = 1;

  dfs(1, 1);
  eulerSize--;
  precalcLog(eulerSize);
  buildRmq(eulerSize);

  while ( k-- ) {
    fscanf(fin, "%d%d", &a, &b);

    fprintf(fout, "%d\n", solve(a, b));
  }

  fclose(fin);
  fclose(fout);

  return 0;
}