Cod sursa(job #1483992)

Utilizator dimavascan94VascanDumitru dimavascan94 Data 10 septembrie 2015 11:57:03
Problema Algoritmul lui Dijkstra Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.95 kb
#include <vector>
#include <string.h>
#include <stdio.h>
using namespace std;

struct Edge
{
	int destination;
	int cost;
	Edge(int dest, int c)
	{
		destination = dest;
		cost = c;
	}
};

unsigned int costs[50005], heapCosts[50005], source, dest, cost;
vector<vector<Edge*>> graph;
int i, n, m, nodesAndPoz[50005], pozAndNodes[50005], current, nmbUnvisited, sizel;

void pushDown(int pos)
{
	int aux = pos;

	if ((pos * 2 + 1 < nmbUnvisited && pos * 2 + 1 != -1) && heapCosts[aux] > heapCosts[pos * 2 + 1])	aux = pos * 2 + 1;
	if ((pos * 2 + 2 < nmbUnvisited && pos * 2 + 2 != -1) && heapCosts[aux] > heapCosts[pos * 2 + 2])	aux = pos * 2 + 2;
	if (aux != pos)
	{
		int nmb = nodesAndPoz[pozAndNodes[aux]];
		nodesAndPoz[pozAndNodes[aux]] = nodesAndPoz[pozAndNodes[pos]];
		nodesAndPoz[pozAndNodes[pos]] = nmb;

		nmb = pozAndNodes[aux];
		pozAndNodes[aux] = pozAndNodes[pos];
		pozAndNodes[pos] = nmb;

		nmb = heapCosts[aux];
		heapCosts[aux] = heapCosts[pos];
		heapCosts[pos] = nmb;

		pos = aux;
		pushDown(aux);
	}
}

void pushUp(int pos)
{
	int aux = pos;

	if ((pos - 1) / 2 >= 0 && heapCosts[aux] < heapCosts[(pos - 1) / 2])	aux = (pos - 1) / 2;
	if (aux != pos)
	{
		int nmb = nodesAndPoz[pozAndNodes[aux]];
		nodesAndPoz[pozAndNodes[aux]] = nodesAndPoz[pozAndNodes[pos]];
		nodesAndPoz[pozAndNodes[pos]] = nmb;

		nmb = pozAndNodes[aux];
		pozAndNodes[aux] = pozAndNodes[pos];
		pozAndNodes[pos] = nmb;

		nmb = heapCosts[aux];
		heapCosts[aux] = heapCosts[pos];
		heapCosts[pos] = nmb;

		pos = aux;
		pushUp(aux);
	}
}

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

	scanf("%d%d", &n, &m);

	nmbUnvisited = n;
	for (i = 0; i < 50005; ++i) costs[i] = 4000000000;
	for (i = 0; i < 50005; ++i) heapCosts[i] = 4000000000;
	memset(nodesAndPoz, -1, 50005 * 4);
	memset(pozAndNodes, -1, 50005 * 4);
	costs[1] = 0;
	heapCosts[0] = 0;
	for (i = 0; i < n; i++) nodesAndPoz[i + 1] = i;
	for (i = 0; i < n; i++) pozAndNodes[i] = i + 1;

	graph = vector<vector<Edge*>>(n + 1);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &source, &dest, &cost);
		graph.at(source).push_back(new Edge(dest, cost));
	}

	while (nmbUnvisited>0)
	{
		current = pozAndNodes[0];
		nodesAndPoz[pozAndNodes[0]] = -1;
		nodesAndPoz[pozAndNodes[nmbUnvisited - 1]] = 0;
		pozAndNodes[0] = pozAndNodes[nmbUnvisited - 1];
		pozAndNodes[nmbUnvisited - 1] = -1;
		heapCosts[0] = heapCosts[nmbUnvisited - 1];
		heapCosts[nmbUnvisited--] = 4000000000;
		pushDown(0);
		sizel = graph[current].size();

		for (i = 0; i < sizel; ++i)
		{
			Edge * edge = graph.at(current).at(i);
			if (costs[edge->destination]>costs[current] + edge->cost)
			{
				costs[edge->destination] = costs[current] + edge->cost;
				heapCosts[nodesAndPoz[edge->destination]] = costs[current] + edge->cost;
				pushUp(nodesAndPoz[edge->destination]);
			}
		}
	}

	for (i = 2; i <= n; ++i)	printf("%d ", costs[i]);
}