Cod sursa(job #525485)

Utilizator cosmyoPaunel Cosmin cosmyo Data 25 ianuarie 2011 12:12:22
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.79 kb
#include <cstdio>
#include <vector>
#include <set>
#define f first
#define s second
const int INF = 0x3f3f3f3f;
using namespace std;
const int N = 15006;
int nr, p1, p2, ind[2 *N], aint[8 * N], k, n, m, t[N], MAX[18][N], ENTER[N], P[2 * N], v[N], s[18][N];
int c[N];
vector< pair<int, int> > a[N];
vector<int> g[N];
set< pair<int, int> > S;
set< pair<int, int> > :: iterator it;

void apm() {
    int i, j, nod, cost = 0;
    for(i = 2 ;i <= N; ++i)
        c[i] = INF;
	c[1] = 0;
    for(i = 0; i < a[1].size(); ++i)
        S.insert(make_pair(a[1][i].s, a[1][i].f)), t[a[1][i].f] = 1, c[a[1][i].f] = a[1][i].s;
    v[1] = 1;
    for(i = 1; i < n; ++i) {
        nod = (*S.begin()).s;
        v[nod] = 1;
		cost += (*S.begin()).f;
		S.erase(S.begin());
        for(j = 0; j < a[nod].size(); ++j)
            if(!v[a[nod][j].f] && a[nod][j].s < c[a[nod][j].f]) {
                it = S.lower_bound(make_pair(c[a[nod][j].f], a[nod][j].f));
                if(it != S.end())
                    S.erase(it);
                S.insert(make_pair(a[nod][j].s, a[nod][j].f));
                c[a[nod][j].f] = a[nod][j].s;
                t[a[nod][j].f] = nod;
            }
    }
}

void dfs(int k) {
    int i;
    P[++nr] = k;
    ENTER[k] = nr;
    for(i = 0; i < g[k].size(); ++i)
        if(!v[g[k][i]]) {
            v[g[k][i]] = v[k] + 1;
			MAX[0][g[k][i]] = c[g[k][i]];
			s[0][g[k][i]] = k;
            dfs(g[k][i]);
            P[++nr] = k;
        }
}

void build(int st, int dr, int poz) {
    int x = (st + dr) / 2;
    if(st == dr) {
        ind[st] = poz;
        return ;
    }
    build(st, x, poz * 2);
    build(x + 1, dr, poz * 2 + 1);
}

int min(int a, int b) {
    return a < b ? a : b;
}

void update(int poz, int val) {
    int x = ind[poz];
    aint[x] = val;
    for(x /= 2; x; x /= 2)
        aint[x] = v[aint[x * 2]] < v[aint[x * 2 + 1]] ? aint[x * 2] : aint[x * 2 + 1];
}

int query(int st, int dr, int poz) {
    if(dr < p1 || p2 < st)
        return 0;
    if(p1 <= st && dr <= p2)
        return aint[poz];
    int x = (st + dr) / 2;
    int q1 = query(st, x, poz * 2);
    int q2 = query(x + 1, dr, poz * 2 + 1);
    return v[q1] < v[q2] ? q1 : q2;
}

int ask(int p, int q) {
	int k = v[p] - v[q], i, max = 0;
	for(i = 0; (1<<i) <= k; ++i)
		if(k & (1 <<i )) {
			if(max < MAX[i][p])
				max = MAX[i][p];
			p = s[i][p];
		}
//	printf("%d ", q);
	return max;
}

int main() {
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    int i, x, y, C, j;
    scanf("%d %d %d", &n, &m, &k);
    for(i = 1; i <= m; ++i)
        scanf("%d %d %d", &x, &y, &C),  a[x].push_back(make_pair(y, C)), a[y].push_back(make_pair(x, C));
    apm();
	/*
    for(i = 1; i <= n; ++i)
        printf("%d ", t[i]);
    printf("\n");
	*/
    for(i = 1;i <= n; ++i)
        v[i] = 0;
    v[1] = 0;
    for(i = 2; i <= n; ++i)
            g[i].push_back(t[i]), g[t[i]].push_back(i);
    v[1] = 1;
    dfs(1);
    build(1, nr, 1);
	v[0] = INF;
	/*
    for(i = 1; i <= nr; ++i)
        printf("%d ", P[i]);
    printf("\n");
	for(i = 1; i <= 2 * nr; ++i)
		printf("%d ", aint[i]);
	printf("\n");
	*/
	for(i = 1; i <= nr; ++i)
		update(i, P[i]);
	for(i = 1; i <= 15; ++i)
		for(j = 1; j <= n; ++j) {
			s[i][j] = s[i - 1][s[i - 1][j]];
			if(s[i][j])
			MAX[i][j] = max(MAX[i - 1][s[i -1][j]], MAX[i - 1][j]);
		}
	/*for(i = 0; i <= 2; ++i) {
		for(j = 1; j <= n; ++j) 
			printf("%d ", MAX[i][j]);
		printf("\n");
	}
	*/
	int lca ;
    for(i = 1; i <= k; ++i) {
        scanf("%d %d", &x, &y);
        p1 = ENTER[x];
        p2 = ENTER[y];
        if(p1 > p2) {
            C = p1;
            p1 = p2;
            p2 = C;
        }
        lca = query(1, nr, 1);
	//	printf("%d %d %d %d\n", x, ENTER[x], y, ENTER[y]);
		p1 = ask(x, lca);
		p2 = ask(y, lca);
		if(p1 > p2)
			printf("%d\n", p1);
		else
			printf("%d\n", p2);
    }
    return 0;
}