Cod sursa(job #2507641)

Utilizator HumikoPostu Alexandru Humiko Data 10 decembrie 2019 17:35:10
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <cstring>

using namespace std;

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

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

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

static const int NMAX = 15e3+5;

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

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

int n, m, k;

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

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

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

void read () {
	cin>>n>>m>>k;
	for ( int i = 1; i <= m; ++i ) {
		int x, y, c;
		cin>>x>>y>>c;
		edge.push_back({x, y, c});
	}
}

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

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

void dsu (int a, int b) {
	int x = parent(a);
	int y = parent(b);

	if ( cardinal[y] > cardinal[x] ) {
		swap(x, y);
	}

	cardinal[x] += cardinal[y];
	father[y] = x;
}

void genApm() {
	sort(edge.begin(), edge.end(), cmp());

	for ( int i = 0; i < m; ++i ) {
		if ( parent(edge[i].a) != parent(edge[i].b) ) {
			dsu(edge[i].a, edge[i].b);

			//cout<<edge[i].a<<" "<<edge[i].b<<'\n';

			graph[edge[i].a].push_back({edge[i].b, edge[i].cost});
			graph[edge[i].b].push_back({edge[i].a, edge[i].cost});
		}
	}
}

void dfs (int vertex, int depth) {
	level[vertex] = depth;
	//cout<<"dfs: "<<vertex<<'\n';

	for ( auto x:graph[vertex] ) {
		if ( !level[x.first] ) {
			dp[0][x.first] = {vertex, x.second};
			dfs(x.first, depth+1);
		}
	}
}

void getToLevel(int &vertex, int dist, int &ans) {
	while (dist) {
		ans = max(ans, dp[Log2[dist]][vertex].second);
		vertex = dp[Log2[dist]][vertex].first; 
		dist -= (1<<Log2[dist]);
	}
}

void getToLCA (int &x, int &y, int &ans) {
	for (int i = Log2[n]; i >= 0; --i ) {
		if ( dp[i][x].first != dp[i][y].first ) {
			ans = max (ans, max(dp[i][x].second,
								dp[i][y].second));
			x = dp[i][x].first;
			y = dp[i][y].first;
		}
	}
}

int answer (int x, int y) {
	int ans = 0;

	//cout<<x<<" "<<y<<" ";
	//cout<<'\n';
	//cout<<"level "<<level[x]<<" "<<level[y]<<" ";
	if ( level[x] > level[y] ) {
		swap(x, y);
	}

	getToLevel(y, level[y]-level[x], ans);
	getToLCA(x, y, ans);

	if ( x != y ) {
		ans = max(ans, max(dp[0][x].second,
						   dp[0][y].second));
	}

	return ans;
}

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

	for ( int i = 1; i <= NMAX-5; ++i ) {
		father[i] = i;
		cardinal[i] = 1;
	}

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

	read();
	genApm();
	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-1][j].second, dp[i-1][dp[i-1][j].first].second);
		}
	}

	for ( int i = 1; i <= k; ++i ) {
		int x, y;
		cin>>x>>y;
		cout<<answer(x, y)<<'\n';
	}
}