Cod sursa(job #1500504)

Utilizator DacianBocea Dacian Dacian Data 12 octombrie 2015 02:13:05
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.59 kb
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <vector>
#include <bitset>
#include <cstring>
using namespace std;
int H[15001], c[15001], P[15001], N, cnt = 0, M, par[15001], K, Str[16][15001], cost[16][15001], depth[15001],MD=0,leg[50000];
bitset<15001> v;
vector<pair<int,int>>child[15001];
const int inf = (1 << 30);
int U = 0, root = 1;
const int lg = 16;
const int o =50000;
int e[o], d[o], h[o], C[lg][o];
struct nod
{
	nod * next;
	int first;
	int second;
}; 
nod* No[15001];
void euler(int current, int& U, int dist){
	e[U] = current;
	d[U] = dist;
	depth[current] = dist;
	if (MD < dist) MD = dist;
	if (h[current] == -1)h[current] = U;
	for (auto&R:child[current]){
		Str[0][R.first] = current;
		cost[0][R.first] = R.second;
		++U;
		euler(R.first, U, dist + 1);
		++U;
		e[U] = current;
		d[U] = dist;
	}
}
void BA() {
	for (int j = 1; (1 << j) <= MD; j++) {
		for (int i = 1; i <= N; i += 1) {
			Str[j][i] = Str[j - 1][Str[j - 1][i]];
			if (cost[j - 1][i]>cost[j - 1][Str[j - 1][i]])
				cost[j][i] = cost[j - 1][i];
			else cost[j][i] = cost[j - 1][Str[j - 1][i]];
		}
	}
}

int min2(int node, int A) {
	int result = -1;
	for (int j = depth[node] - depth[A]; j > 0; j -= (1 << leg[j])) {
		result = result > cost[leg[j]][node] ? result : cost[leg[j]][node];
		node = Str[leg [j]][node];
	}
	return result;
}
void rmq2(){
	int j, N = U;
	for (int i = 0; i < N; ++i)
		C[0][i] = i;
	for (j = 1; 1 << j <= N; ++j)
	for (int i = 0; i + (1 << j) - 1 < N; ++i)
	if (d[C[j - 1][i]] < d[C[j - 1][i + (1 << (j - 1))]])
		C[j][i] = C[j - 1][i];
	else
		C[j][i] = C[j - 1][i + (1 << (j - 1))];
}
int lca(int a, int b){
	int p1 = h[a], p2 = h[b];
	if (p2 < p1)swap(p2, p1);
	int k = 0, pow = 1;
	while (pow <= p2 - p1 + 1){ pow <<= 1; ++k; }
	pow >>= 1;
	--k;
	int index = d[C[k][p1]] <= d[C[k][p2 - pow + 1]] ? C[k][p1] : C[k][p2 - pow + 1];
	return e[index];
} 
void per(int k){
	if (k > 1){
		int f = k >> 1;
		if (c[H[f]] > c[H[k]]){
			swap(H[k], H[f]);
			swap(P[H[k]], P[H[f]]);
			per(f);
		}
	}
}
void sift(int poz)
{
	int f;
	if (poz <= cnt / 2){
		if (poz * 2 + 1 <= cnt)
		if (c[H[poz * 2]] < c[H[poz * 2 + 1]])
			f = 2 * poz;
		else f = 2 * poz + 1;
		else f = 2 * poz;
		if (c[H[poz]]>c[H[f]]){
			swap(H[poz], H[f]);
			swap(P[H[poz]], P[H[f]]);
			sift(f);
		}
	}
}

void add(int x){
	H[++cnt] = x;
	P[x] = cnt;
	per(cnt);
}
int rad(){
	int x = H[1];
	swap(H[1], H[cnt]);
	swap(P[H[1]], P[H[cnt]]);
	--cnt;
	sift(1);
	return x;
}
int main(){
	freopen("radiatie.in", "r", stdin);
	freopen("radiatie.out", "w", stdout);
	scanf("%d%d%d", &N, &M,&K);
	for (int i = 2; i <= N; ++i){
		c[i] = inf;
	}
	c[1] = 0;
	for (int i = 1; i <= M; ++i){
		int a, b, d;
		scanf("%d%d%d", &a, &b, &d);
		nod* n = new nod;
		n->first = b;
		n->second = d;
		n->next = No[a];
		No[a] = n;
		n = new nod;
		n->first = a;
		n->second = d;
		n->next = No[b];
		No[b] = n;
	}
	add(1);
	while (cnt != 0){
		int x = rad();
		v[x] = 1;
		child[par[x]].push_back(make_pair(x,c[x]));
		for (nod*i = No[x]; i != 0; i = i->next){
			if (!v[i->first] && i->second < c[i->first]){
				c[i->first] = i->second;
				par[i->first] = x;
				if (!P[i->first])add(i->first);
				else per(P[i->first]);
			}
		}
	}
	memset(h, -1, sizeof(h));
	euler(1,U,0);
	rmq2();
	for (int i = 2; i <= U; ++i)
		leg[i] = 1 + leg[i / 2];
	BA();
	int a, b;
	for (int G = 0; G < K; ++G){
		scanf("%d%d", &a, &b);
		int LC = lca(a, b), m1 = min2(a, LC), m2 = min2(b, LC);
		int min1 = m1 > m2 ? m1 : m2;
		printf("%d\n", min1);
	}
	
}