Cod sursa(job #2906906)

Utilizator andreic06Andrei Calota andreic06 Data 27 mai 2022 19:44:18
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.1 kb
#include <bits/stdc++.h>

using namespace std;
const int NMAX = 15e3;
const int MAX_LOG = 17;
const int ROOT = 1;
const int ERR = -1;
const int INF = 2e9;

int n, m, q;
struct define_edge {
   int from, to, cost;
}; vector<define_edge> edges;
bool sort_cond ( define_edge first, define_edge second ) {
   if ( first.cost == second.cost )
     return first.to < second.to;
   return first.cost < second.cost;
}

int father[1 + NMAX];
int get_sup ( int node ) {
   if ( father[node] != node )
     return father[node] = get_sup ( father[node] );
   return node;
}
void join ( int first, int second ) {
    int sup_first = get_sup ( first );
    int sup_second = get_sup ( second );
    father[sup_first] = sup_second;
}
void init_DSU () {
   for ( int node = 1; node <= NMAX; node ++ )
      father[node] = node;
}

vector<define_edge> answer;
void MSP () {
    sort ( edges.begin (), edges.end (), sort_cond );
    init_DSU ();
    for ( auto edge : edges ) {
       int first = edge.from, second = edge.to;
       int cost = edge.cost;
       if ( get_sup (first) != get_sup (second) ) {
         join ( first, second );
         answer.push_back ( { first, second, cost } );
       }
    }
}

bool visited[1 + NMAX]; int height[1 + NMAX];
vector<define_edge> graph[1 + NMAX];
define_edge parent[1 + MAX_LOG][1 + NMAX];

int lifting[1 + MAX_LOG][1 + NMAX];
void init_lifting () {
   for ( int p = 0; p <= MAX_LOG; p ++ )
      for ( int node = 1; node <= n; node ++ )
         lifting[p][node] = INF;
}
void bfs ( int p, int start ) {
    queue<int> bfs_q;
    bfs_q.push ( start );
    while ( !bfs_q.empty () ) {
       int root = bfs_q.front (); bfs_q.pop ();
       visited[root] = true;

       if ( p == 0 )
         lifting[p][root] = parent[0][root].cost;
       else {
         lifting[p][root] = max ( lifting[p - 1][root], lifting[p - 1][parent[p - 1][root].to] );
         parent[p][root].to = parent[p - 1][parent[p - 1][root].to].to;
       }
       for ( auto obj : graph[root] )
          if ( !visited[obj.to] )
            bfs_q.push ( obj.to );
    }
}
void dfs ( int root ) {
   visited[root] = true;
   for ( auto object : graph[root] ) {
      int next_node = object.to;
      int cost = object.cost;
      if ( !visited[next_node] ) {
        height[next_node] = height[root] + 1;
        parent[0][next_node] = { ERR, root, cost };
        dfs ( next_node );
      }
   }
}
void compute_tree () {
    for ( auto edge : answer ) {
       graph[edge.from].push_back ( { ERR, edge.to, edge.cost } );
       graph[edge.to].push_back ( { ERR, edge.from, edge.cost } );
    }
    dfs ( ROOT ); init_lifting ();
    for ( int p = 0; p <= MAX_LOG; p ++ ) {
       for ( int node = 1; node <= n; node ++ )
          visited[node] = false;
       bfs ( p, ROOT );
    }
}

int query ( int first, int second ) {
   if ( height[first] < height[second] )
     swap ( first, second );

   int answer = -INF; height[parent[0][ROOT].to] = -INF;
   for ( int p = MAX_LOG; p >= 0; p -- ) {
      if ( height[parent[p][first].to] >= height[second] ) {
        answer = max ( answer, lifting[p][first] );
        first = parent[p][first].to;
      }
   }

   for ( int p = MAX_LOG; p >= 0; p -- ) {
      if ( parent[p][first].to != parent[p][second].to ) {
        answer = max ( answer, lifting[p][first] );
        answer = max ( answer, lifting[p][second] );
        first = parent[p][first].to;
        second = parent[p][second].to;
      }
   }

   if ( first != second ) {
     int p = 0;
     while ( parent[p][first].to != parent[p][second].to )
        p ++;
     answer = max ( answer, lifting[p][first] );
   }
   return answer;
}

int main()
{
   ifstream in ( "radiatie.in" );
   ofstream out ( "radiatie.out" );
   in >> n >> m >> q;
   for ( int i = 1; i <= n; i ++ ) {
      int a, b, cost; in >> a >> b >> cost;
      edges.push_back ( { a, b, cost } );
   }
   MSP (); compute_tree ();
   for ( int index = 1; index <= q; index ++ ) {
      int a, b; in >> a >> b;
      out << query ( a, b ) << "\n";
   }

    return 0;
}