Cod sursa(job #499563)

Utilizator IgnitionMihai Moraru Ignition Data 10 noiembrie 2010 10:57:52
Problema Algoritmul lui Dijkstra Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <stdio.h>
#include <vector>

using namespace std;

#define MN (50001)
#define INF (50000001) // MN*1000+1

int N; // nodes
int M; // edges
vector<int> g[MN]; // graph
vector<int> c[MN]; // cost
int h[MN+1]; // heap, h[0] contains heap size
int d[MN]; // distance
int p[MN]; // position in the heap

void down_heap(int i);
void up_heap(int i);
void dijkstra(int snode);
void pop_heap();
void push_heap(int node);

int main()
{
	freopen("dijkstra.in", "r", stdin);
	freopen("dijkstra.out", "w", stdout);

	int i, A, B, C;

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

	for(i = 0; i < M; ++i) {
		scanf("%d %d %d", &A, &B, &C); --A; --B;
		g[A].push_back(B);
		c[A].push_back(C);
	}

	dijkstra(0);

	for(i = 1; i < N; ++i)
		printf("%d ", d[i] == INF? 0 : d[i]);

	return 0;
}

void dijkstra(int snode)
{
	int i, n1, n2;
	for(i = 0; i < N; ++i) {
		d[i] = INF;
		p[i] = -1;
	}
	h[0] = d[snode] = 0;
	for(push_heap(snode); h[0]; pop_heap()) {
		n1 = h[1];
		for(i = 0; i < g[n1].size(); ++i) {
			n2 = g[n1][i];
			if(d[n1]+c[n1][i] < d[n2]) {
				d[n2] = d[n1]+c[n1][i];
				if(p[n2] > 0)
					up_heap(p[n2]);
				else push_heap(n2);
			}
		}
	}
}

void up_heap(int i)
{
	int tmp;
	for(; i > 1 && d[h[i]] < d[h[i/2]]; i /= 2) {
		p[h[i]] = i/2;
		p[h[i/2]] = i;
		tmp = h[i];
		h[i] = h[i/2];
		h[i/2] = tmp;
	}
}

void down_heap(int i)
{
	int j = i, tmp;
	while(1) {
		if(2*i < h[0] && d[h[2*i]] < d[h[i]])
			j = 2*i;
		if(2*i+1 < h[0] && d[h[2*i+1]] < d[h[j]])
			j = 2*i+1;
		if(d[h[j]] < d[h[i]]) {
			p[h[i]] = j;
			p[h[j]] = i;
			tmp = h[i];
			h[i] = h[j];
			h[j] = tmp;
			i = j;
		} else break;
	}
}

void push_heap(int node)
{
	h[++h[0]] = node;
	p[node] = h[0];
	up_heap(h[0]);
}

void pop_heap()
{
	p[h[1]] = -1;
	h[1] = h[h[0]--];
	p[h[1]] = 1;
	down_heap(1);
}