Cod sursa(job #2506360)

Utilizator HumikoPostu Alexandru Humiko Data 7 decembrie 2019 21:35:22
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <vector>
#include <algorithm>

using namespace std;

//#include <iostream>
#include <fstream>

ifstream cin ("input.in");
ofstream cout ("output.out");

//ifstream cin ("radiatie.in");
//ofstream cout ("radiatie.out");

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

class cmp {
public:
	const bool operator () ( const edgeType &a, const edgeType &b ) {
		return a.cost < b.cost;
	}
};

static const int NMAX = 15e3+5;

int n, m, k;

int father[NMAX];
int level[NMAX];
int Log2[NMAX];

pair <int, int> dp[20][NMAX];

vector <pair<int, int>> graph[NMAX];
vector <edgeType> edge;

void read() {
	cin>>n>>m>>k;

	for ( int i = 1; i <= m; ++i ) {
		int a, b, c;
		cin>>a>>b>>c;
		edge.push_back({a, b, c});
	}
}

int parent (int vertex) {
	if ( vertex == father[vertex] ) {
		return vertex;
	}

	father[vertex] = parent(father[vertex]);
	return father[vertex];
}

void dsu (int a, int b) {
	father[parent(a)] = parent(b); 
}

void getApm() {
	sort(edge.begin(), edge.end(), cmp());
	
	for ( int i = 1; i <= n; ++i ) {
		father[i] = i;
	}

	for ( auto x:edge ) {
		if ( parent(x.a) != parent(x.b) ) {
			dsu(x.a, x.b);
			graph[x.a].push_back({x.b, x.cost});
			graph[x.b].push_back({x.a, x.cost});
		}
	}
}

int l;

void dfs (int vertex, int depth) {
	level[vertex] = depth;

	for ( auto x:graph[vertex] ) {
		if ( !level[x.first] ) {
			dp[0][x.first].first = vertex; //nod
			dp[0][x.first].second = x.second; //cost

			dfs(x.first, depth+1);
		}
	}
}

int parent (int vertex, int dist) {
	for ( int i = Log2[n]; i >= 0 && dist > 0; --i ) {
		if ( (1<<i) > dist ) {
			continue;
		}

		vertex = dp[i][vertex].first;
		dist -= (1<<i);
	}

	return vertex;
}

int getLCA (int x, int y) {
	if ( level[x] > level[y] ) {
		swap(x, y);
	}

	while ( level[y] > level[x] ) {
		y = parent(y, level[y]-level[x]);
	}

	return y;
}

int getEdge (int x, int y) {
	if ( level[x] > level[y] ) {
		swap(x, y);
	}
 
	int dist = level[y]-level[x];
 
	int ans = 0;
	for ( int i = Log2[n]; i >= 0; --i ) {
		if ( (1<<i) > dist ) {
			continue;
		}
 
		ans = max(dp[i][y].second, ans);
		dist -= (1<<i);
	}
	return ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	for ( int i = 2; i <= NMAX-5; ++i ) {
		Log2[i] = Log2[i/2]+1;
	}

	read();
	getApm();
	dfs(1, 1);

	for ( int i = 1; i <= Log2[n]; ++i ) {
		for ( int j = 1; j <= n; ++j ) {
			dp[i][j].first = dp[i-1][dp[i-1][j].first].first;
			dp[i][j].second = max(dp[i][j].second, dp[i-1][dp[i-1][j].first].second);
		}
	}

	for ( int i = 1; i <= k; ++i ) {
		int x, y;
		cin>>x>>y;

		int z = getLCA(x, y);

		int firstEdge = getEdge(x, z);
		int secondEdge = getEdge(y, z);

		cout<<max(firstEdge, secondEdge)<<'\n';
	}
}