Cod sursa(job #797061)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 13 octombrie 2012 12:41:43
Problema Lazy Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb

#include <cstdio>

const int MAX_SIZE(200001);

struct edge
{
	int a;
	int b;
	long long cost1;
	long long cost2;
} edges [MAX_SIZE];

inline bool operator < (struct edge a, struct edge b)
{
	return a.cost1 < b.cost1 || (a.cost1 == b.cost1 && a.cost2 > b.cost2);
}

int heap [MAX_SIZE];
int heap_size;

int path [MAX_SIZE];

int forest [MAX_SIZE];

int v, e;

inline void read (void)
{
	std::freopen("lazy.in","r",stdin);
	std::scanf("%d%d",&v,&e);
	heap_size = e;
	int *initialize(heap), index(1);
	for (struct edge *iterator(edges + 1), *end(edges + e) ; iterator <= end ; ++iterator, ++initialize, ++index)
	{
		std::scanf("%d%d%lld%lld",&(iterator->a),&(iterator->b),&(iterator->cost1),&(iterator->cost2));
		forest[index] = -1;
		*initialize = index;
	}
	std::fclose(stdin);
}

inline void print (void)
{
	std::freopen("lazy.out","w",stdout);
	for (int *iterator(path), *end(path + v - 1) ; iterator < end ; ++iterator)
		std::printf("%d\n",*iterator);
	std::fclose(stdout);
}

inline void increase (int index)
{
	int left((index << 1) + 1), right(left + 1), smallest;
	while (true)
	{
		if (left < heap_size && edges[heap[left]] < edges[heap[index]])
			smallest = left;
		else
			smallest = index;
		if (right < heap_size && edges[heap[right]] < edges[heap[smallest]])
			smallest = right;
		if (smallest == index)
			break;
		heap[index] ^= heap[smallest];
		heap[smallest] ^= heap[index];
		heap[index] ^= heap[smallest];
		index = smallest;
		left = (index << 1) + 1;
		right = left + 1;
	}
}

inline void pop (void)
{
	--heap_size;
	*heap = heap[heap_size];
	increase(0);
}

inline void build_heap (void)
{
	for (int index((heap_size - 1) >> 1) ; index ; --index)
		increase(index);
}

int find (int x)
{
	if (forest[x] < 0)
		return x;
	forest[x] = find(forest[x]);
	return forest[x];
}

inline void merge (int x, int y)
{
	x = find(x);
	y = find(y);
	if (forest[y] < forest[x])
	{
		x ^= y;
		y ^= x;
		x ^= y;
	}
	forest[x] += forest[y];
	forest[y] = forest[x];
}

inline void Kruskal (void)
{
	build_heap();
	int *path_add(path), *end(path + v - 1);
	while (path_add < end)
	{
		while (find(edges[*heap].a) == find(edges[*heap].b))
			pop();
		*path_add = *heap;
		++path_add;
		merge(edges[*heap].a,edges[*heap].b);
		pop();
	}
}

int main (void)
{
	read();
	Kruskal();
	print();
	return 0;
}