Cod sursa(job #7569)

Utilizator mugurelionutMugurel-Ionut Andreica mugurelionut Data 21 ianuarie 2007 18:05:16
Problema Radiatie Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.18 kb
// O(K * logM * logN + M * (logM + logN))

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <algorithm>
#include <vector>

using namespace std;

#define NMAX 15100
#define KMAX 15100
#define MMAX 32000
#define INF 1100000000

#define len(x) (ve[x].first)
#define c1(x) (ve[x].second.first)
#define c2(x) (ve[x].second.second)

vector<pair<int, pair<int, int> > > ve;
int tata[NMAX], h[NMAX], timpuni[NMAX], a[KMAX], b[KMAX], tuni[KMAX];
int i, j, l, k, N, M, K, cnt = 0;
int tmin, tmax, tmid, tok;

inline int findt(int x, int tlim)
{
	int tx = x;

	while (tata[tx] != 0 && timpuni[tx] <= tlim)
		tx = tata[tx];

	return tx;
}

// union by rank -> for connected components (also storing the time a union is made)

inline void uni(int x, int y)
{
	int tx, ty;

	tx = x;
	while (tata[tx] != 0)
		tx = tata[tx];

	ty = y;
	while (tata[ty] != 0)
		ty = tata[ty];

	if (tx != ty)
	{
		// union

		if (h[tx] < h[ty])
		{
			tata[tx] = ty;
			timpuni[tx] = k;
		}
		else
		if (h[tx] > h[ty])
		{
			tata[ty] = tx;
			timpuni[ty] = k;
		}
		else // h[tx] == h[ty]
		{
			tata[tx] = ty;
			timpuni[tx] = k;
			h[ty]++;
		}
	}
}

int main()
{
	freopen("radiatie.in", "r", stdin);

	scanf("%d %d %d", &N, &M, &K);

	ve.clear();

	for (k = 1; k <= M; k++)
	{
		scanf("%d %d %d", &i, &j, &l);
		ve.push_back(make_pair(l, make_pair(i, j)));
	}

	for (k = 1; k <= K; k++)
		scanf("%d %d", &a[k], &b[k]);

	sort(ve.begin(), ve.end());

	memset(tata, 0, sizeof(tata));
	memset(timpuni, 0, sizeof(timpuni));
	memset(h, 0, sizeof(h));

	for (k = 0; k < M; k++)
	{
		i = c1(k);
		j = c2(k);

		//fprintf(stderr, "%d %d -> %d\n", i, j, len(k));

		uni(i, j);
	}

	// do some binary search for each of the K pairs

	freopen("radiatie.out", "w", stdout);

	for (k = 1; k <= K; k++)
	{
		if (a[k] == b[k])
			printf("0\n");
		else
		{
			tmin = 0; tmax = tok = M - 1;

			while (tmin <= tmax)
			{
				tmid = (tmin + tmax) >> 1;

				if (findt(a[k], tmid) == findt(b[k], tmid))
					tok = tmid, tmax = tmid - 1;
				else
					tmin = tmid + 1;
			}

			printf("%d\n", len(tok));
		}
	}

	return 0;
}