Cod sursa(job #245836)

Utilizator alextheroTandrau Alexandru alexthero Data 19 ianuarie 2009 00:04:09
Problema Algoritmul lui Dijkstra Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.44 kb
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>

// maximum number of nodes
#define nmax 65536

// starting node
#define source 0

// infinity
#define inf 0x3f3f3f3f

using namespace std;

typedef pair<int, int> ii;

int n, m;

// the graph will be stored as adjecency list, e[i] is a list of nodes accesible from node i, together with the cost
// a pair (x, y) means a path to x with the cost y
vector <ii> e[nmax];

// d[i] will hold the distance from starting node to node i
int d[nmax];

// Dijsktra's algorithm, using priority que from STL
// time complexity: O(M * log N)
void dijkstra(int start)
{
	// all nodes initialy start with distance infinity, except for the starting node
	memset(d, inf, sizeof(d));	
	d[start] = 0;

	// we will use priority que for heap functions in log N, Q is the equivalent of min-heap
	// the pairs (x, y) in Q will mean x is the current distance from node start to y
	// we are keeping them the other way around because the distance is the comparison criteria for the heap
	priority_queue <ii, vector <ii>, greater <ii> > Q;

	Q.push(ii(0, start));
	while(!Q.empty())
	{
		// take first element
		ii aux = Q.top();
		Q.pop();

		// priority queue doesen't have a function for updating elements inside the que
		// thus, we will never remove elements, but check if the distance is the right one (we don't want to 
		// expand from a node more than once for time reasons)
		if(d[aux.second] == aux.first)
		{
			for(vector <ii> :: iterator it = e[aux.second].begin(); it != e[aux.second].end(); ++it)
			{
				// try expanding from aux.second to *it.first with cost *it.second
				if(d[(*it).first] > d[aux.second] + (*it).second)
				{
					// we found a better path!

					d[(*it).first] = d[aux.second] + (*it).second;
					Q.push(ii(d[(*it).first], (*it).first ));
				}
			}
		}
	}
}

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

	// scan number of nodes and edges
	scanf("%d%d", &n, &m);
	for(int i = 0; i < m; i++) {
		int firstNode, secondNode, cost;
		scanf("%d%d%d", &firstNode, &secondNode, &cost);
		firstNode--, secondNode--;
		e[firstNode].push_back(ii(secondNode, cost));
		e[secondNode].push_back(ii(firstNode, cost));
	}

	// find the distances from start node to all others
	dijkstra(source);
	for(int i = 0; i < n; i++) 
		if(i != source) {
			if(d[i] == inf) d[i] = 0;
			printf("%d ", d[i]);
	//		printf("Distance from %d to %d is: %d\n", source, i, d[i]);
		}

	return 0;
}