Cod sursa(job #2208239)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 28 mai 2018 20:56:07
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.11 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

#define MAX(a , b) (((a) < (b)) ? (b) : (a))
#define MIN(a , b) (((a) < (b)) ? (a) : (b))

int const nmax = 30000;
int const lgmax = 25;
int const inf = 1000000000;

struct Edge{
  int x;
  int y;
  int cost;
  bool operator < (Edge const &a) const{
    return cost < a.cost;
  }
};

vector < Edge > g[5 + nmax];

int n , m , q;

///APM begins here
int mult[5 + nmax];
int msize[5 + nmax];

int jump(int a){
  if(a != mult[a]) {
    mult[a] = jump(mult[a]);
    return mult[a];
  } else
    return a;
}

void unite(int x , int y){
  if(msize[x] < msize[y]){
    mult[x] = y;
    msize[y] += msize[x];
    msize[x] = 0;
  } else{
    mult[y] = x;
    msize[x] += msize[y];
    msize[y] = 0;
  }
}

void computeapm(){
  for(int i = 1 ; i <= n ;i++){
    mult[i] = i;
    msize[i] = 1;
  }

  vector < Edge > pq;

  for(int i = 1 ; i <= m ;i++){
    int x , y , c;
    in >> x >> y >> c;
    pq.push_back({x , y , c});
  }
  sort(pq.begin() , pq.end());

  for(int i = 0 ; i < pq.size() ;i++){
    if(jump(pq[i].x) != jump(pq[i].y)){
      unite(jump(pq[i].x) , jump(pq[i].y));
      g[pq[i].x].push_back({pq[i].x , pq[i].y , pq[i].cost});
      g[pq[i].y].push_back({pq[i].x , pq[i].x , pq[i].cost});
    }
  }
}

///LCA begins here
int level[5 + nmax];

int euler[5 + nmax * 3] , eulerp;
int pos[5 + nmax];

int far[5 + lgmax][5 + nmax * 3];
int fars[5 + lgmax][5 + nmax];

void dfs(int node , int parent){

  level[node] = level[parent] + 1;

  euler[++eulerp] = node;
  pos[node] = eulerp;

  for(int h = 0 ; h < g[node].size() ;h++){
    int to = g[node][h].y;
    if(to != parent){
      dfs(to , node);
      euler[++eulerp] = node;

      far[0][to] = node;
      fars[0][to] = g[node][h].cost;
    }
  }
}

int lg[5 + nmax * 3];

int rmq[5 + lgmax][5 + nmax * 3];

void computermq(){

  for(int i = 2 ; i <= nmax * 3 ;i++)
    lg[i] = lg[i / 2] + 1;

  for(int i = 1 ; i <= eulerp ;i++)
    rmq[0][i] = level[euler[i]];
  for(int h = 1 ; h <= lgmax ;h++){
    for(int i = 1 ; i <= eulerp - (1 << h) + 1;i++){
      rmq[h][i] = MIN(rmq[h - 1][i] ,rmq[h - 1][i + (1 << (h - 1))] );
    }
  }
}

int computelca(int x , int y){
  x = pos[x];
  y = pos[y];
  if(y < x)
    swap(x , y);

  int dist = (y - x);
  return MIN(rmq[lg[dist]][x] , rmq[lg[dist]][y - (1 << lg[dist]) + 1]);
}

///The interesting part begins here

void computefar(){
  far[0][1] = 0;
  fars[0][0] = fars[0][1] = -inf;
  for(int h = 1 ; h <= lgmax ; h++){
    for(int i = 1 ; i <= n ;i++){
      far[h][i] = far[h - 1][far[h - 1][i]];
      fars[h][i] = MAX(fars[h - 1][i] , fars[h - 1][far[h - 1][i]] );
      //cout << h << " " << i  <<" "<<  far[h][i] << " " << fars[h][i] << '\n';
    }
  }
}

int getpath(int x , int dist){
  int smax = -inf;
  //cout << dist;
  for(int h = lgmax ; 0 <= h ;h--){
    int jumpval = (1 << h);
    if(jumpval <= dist){

      dist -= jumpval;
      smax = MAX(smax , fars[h][x]);
      //cout << smax << " " << fars[h][x] << '\n';
      x = far[h][x];
    }
  }
  return smax;
}

int solve(int x , int y){
  int lca = computelca(x , y);

  return MAX(getpath(x , level[x] - lca) , getpath(y , level[y] -  lca));
}

void debugmode(){
  for(int i = 1 ; i <= eulerp ;i++)
    cout << euler[i] << " " ;
  cout << '\n' << '\n';

  for(int i = 1 ; i <= n ;i++) {
    for(int j = 1 ; j <= n ; j++){
      cout << i << " " <<j << '\n';
      cout << pos[i] << " " << pos[j] << " " << computelca(i , j) << '\n';
      cout << '\n';
    }
  }
}
int main()
{
  in >> n >> m >> q;
  computeapm(); /// we build the APM
  dfs(1 , 0); /// we compute prerequisites for RMQ
  computermq(); /// we don't really need the LCA, just its level
  computefar();

  //debugmode();
  //*
  for(int i = 1 ; i <= q ;i++){
    int x , y;
    in >> x >> y;
    if(x != y)
      out << solve(x , y) << '\n';
    else
      out << 0 << '\n';
  }
  //*/
  return 0;
}