Pagini recente » Cod sursa (job #951831) | Arhiva de probleme | Cod sursa (job #2677044) | Cod sursa (job #1483302) | Cod sursa (job #2208239)
#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;
}