Cod sursa(job #625945)

Utilizator andra23Laura Draghici andra23 Data 25 octombrie 2011 21:44:45
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.02 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>

using namespace std;

const int MAXN = 15010;
const int MAXM = 30010;
const int MAXK = 15010;
int t[MAXN], rank[MAXN], used[MAXN], lg[MAXN], level[MAXN];
pair <int, pair <int,int> > edge[MAXM];
vector <pair <int,int> > v[MAXN];
int maxRadiation[MAXN][20], ancestor[MAXN][20];

int find(int x) {
	int y = x;
	while (x != t[x]) {
		x = t[x];
	}

	while (y != t[y]) {
		int aux = t[y];
		t[y] = x;
		y = aux;
	}
	return x;
}

void union_sets(int x, int y) {
	x = find(x);
	y = find(y);
	if (rank[x] > rank[y]) {
		t[y] = x;
	} else {
		t[x] = y;
		if (rank[x] == rank[y]) {
			rank[y]++;
		}
	}
}

void calculateLog(int n) {
	lg[1] = 0;
	for (int i = 2; i <= n; i++) {
		lg[i] = lg[i/2]+1;
	}
}

void dfs(int vertex) {
	used[vertex] = 1;
	for (int i = 0; i < v[vertex].size(); i++) {
		if (used[v[vertex][i].first] == 0) {
			int x = v[vertex][i].first;
			int radiation = v[vertex][i].second;
			level[x] = level[vertex]+1;
			ancestor[x][0] = vertex;
			maxRadiation[x][0] = radiation;
			dfs(x);
		}
	}
}

int findLCA(int x, int y) {
	if (level[x] > level[y]) {
		int aux = x;
		x = y;
		y = aux;
	}
	int diffLevel = level[y] - level[x];
	for (int i = lg[diffLevel]; i >= 0; i--) {
		if ((1<<i) <= diffLevel) {
			y = ancestor[y][i];
			diffLevel -= (1<<i);
		}
	}
	if (x == y) {
		return x;
	}

	for (int i = lg[level[x]]; i >= 0; i--) {
		if (ancestor[x][i] != ancestor[y][i]) {
			x = ancestor[x][i];
			y = ancestor[y][i];
		}
	}
	return ancestor[x][0];
}

int calculateMaxRadiation(int lca, int y) {
	int diffLevel = level[y] - level[lca];
	int result = 0;
	for (int i = lg[diffLevel]; i >= 0; i--) {
		if ((1<<i) <= diffLevel) {
			result = max(result, maxRadiation[y][i]);
			y = ancestor[y][i];
			diffLevel -= (1<<i);
		}
	}
	return result;
}

int main() {
	ifstream f("radiatie.in");
	ofstream g("radiatie.out");

	int m, n, k;
	f >> n >> m >> k;

	int x, y, cost;
	for (int i = 1; i <= m; i++) {
		f >> x >> y >> cost;
		edge[i] = make_pair(cost, make_pair(x,y));
	}

	for (int i = 1; i <= n; i++) {
		t[i] = i;
		rank[i] = 1;
	}
	sort(edge+1, edge+m+1);
	
	for (int i = 1; i <= m; i++) {
		int x = edge[i].second.first;
		int y = edge[i].second.second;
		cost = edge[i].first;
		if (find(x) != find(y)) {
			v[x].push_back(make_pair(y,cost));
			v[y].push_back(make_pair(x,cost));
			union_sets(x,y);
		}
	}

	calculateLog(n);
	for (int i = 1; i <= n; i++) {
		if (used[i] == 0) {
			level[i] = 1;
			ancestor[i][0] = -1;
			dfs(i);
		}
	}

	for (int j = 1; j <= lg[n]; j++) {
		for (int i = 1; i <= n; i++) {
			ancestor[i][j] = -1;
		}
	}

	for (int j = 1; j <= lg[n]; j++) {
		for (int i = 1; i <= n; i++) {
			if (ancestor[i][j-1] != -1) {
				ancestor[i][j] = ancestor[ancestor[i][j-1]][j-1];
				maxRadiation[i][j] = max(maxRadiation[i][j-1],
					maxRadiation[ancestor[i][j-1]][j-1]);
			}
		}
	}
	
	for (int i = 1; i <= k; i++) {
		f >> x >> y;
		int lca = findLCA(x, y);
		int result = max(calculateMaxRadiation(lca, x),
			calculateMaxRadiation(lca, y));
		g << result << '\n';
	}

	return 0;
}