Cod sursa(job #2293568)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 1 decembrie 2018 10:56:37
Problema Algoritmul lui Dijkstra Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.99 kb
#include <bits/stdc++.h>
using namespace std;

template <typename type>
class Graph {

public:

	struct Edge {	
		int from, to; 
		type cost; 
	};

	int n;
	vector<Edge> edg;
	vector<vector<int>> gph;

	Graph(int _n) : n(_n) {
		gph.resize(n); }
	
	virtual int addEdge(int from, int to, type cost = 1) {
		assert(0 <= min(from, to) and max(from, to) < n);
		int id = (int) edg.size();
		gph[from].push_back(id);
		edg.push_back({from, to, cost}); 
		return id; }
};

template <typename type>
vector<type> dijkstraSet(const Graph<type> &g, vector<int> lst) {
	set<pair<type, int>> mst;
	vector<type> dst(g.n, numeric_limits<type> :: max());
	for (int src : lst) {
		assert(0 <= src and src < g.n);
		dst[src] = 0; mst.insert(make_pair(0, src)); }
	while (!mst.empty()) {
		int x = mst.begin() -> second; mst.erase(mst.begin());
		for (int id : g.gph[x]) {
			auto &ed = g.edg[id]; int y = ed.from ^ ed.to ^ x;
			if (dst[y] > dst[x] + ed.cost) {
				mst.erase(make_pair(dst[y], y));
				dst[y] = dst[x] + ed.cost;
				mst.insert(make_pair(dst[y], y)); } } } 
	return dst; }

template <typename type>
vector<type> dijkstraSet(const Graph<type> &g, int src) {
	return dijkstraSet(g, vector<int>(1, src)); }

template <typename type>
vector<type> dijkstraPriorityQueue(const Graph<type> &g, vector<int> lst) {
	vector<type> dst(g.n, numeric_limits<type> :: max());
	priority_queue<pair<type, int>, vector<pair<type, int>>, greater<pair<type, int>>> prq;
	for (int src : lst) {
		assert(0 <= src and src < g.n);
		dst[src] = 0; prq.push(make_pair(0, src)); }
	while (!prq.empty()) {
		type c = prq.top().first; int x = prq.top().second; prq.pop();
		if (dst[x] != c) {
			continue; }
		for (int id : g.gph[x]) {
			auto &ed = g.edg[id]; int y = ed.from ^ ed.to ^ x;
			if (dst[y] > dst[x] + ed.cost) {
				dst[y] = dst[x] + ed.cost;
				prq.push(make_pair(dst[y], y)); } } }
	return dst; }

template <typename type>
vector<type> dijkstraPriorityQueue(const Graph<type> &g, int src) {
	return dijkstraPriorityQueue(g, vector<int>(1, src)); }

template <typename type>
vector<type> bellmanFord(const Graph<type> &g, vector<int> lst, const int lim = 1000000) {
	vector<type> dst(g.n, numeric_limits<type> :: max());
	deque<int> que; vector<bool> oki(g.n, false); int cnt = 0;
	for (int src : lst) {
		assert(0 <= src and src < g.n);
		dst[src] = 0; oki[src] = true; que.push_back(src); }
	while (que.size()) {
		int x = que.front(); oki[x] = false; que.pop_front();
		for (int id : g.gph[x]) {
			auto &ed = g.edg[id]; int y = ed.from ^ ed.to ^ x;
			if (dst[y] > dst[x] + ed.cost) {
				dst[y] = dst[x] + ed.cost;
				if (!oki[y]) {
					oki[y] = true; ++cnt; que.push_back(y);
					if (cnt == lim) {
						return vector<type>(); } } } } }
	return dst; }

template <typename type>
vector<type> bellmanFord(const Graph<type> &g, int src, const int lim = 1000000) {
	return bellmanFord(g, vector<int>(1, src), lim); }

/*
template <typename type>
class DirectedGraph : public Graph<type> {

public:

	using Graph<type> :: n;
	using Graph<type> :: gph;
	using Graph<type> :: edg;
	
	DirectedGraph(int _n) :
		Graph<type>(_n) {}

	int addEdge(int from, int to, type cost = 1) {
		assert(0 <= min(from, to) and max(from, to) < n);
		int id = (int) edg.size(); 
		gph[from].push_back(id);
		edg.push_back({from, to, cost}); 
		return id; }

	DirectedGraph<type> reverseGraph(void) {
		DirectedGraph<type> rvg(n);
		for (auto &ed : edg) {
			rvg.addEdge(ed.to, ed.from, ed.cost); }
		return rvg; }
};
 */

const int DIM = 50005;

Graph<int> g(DIM);

int main(void) {
	freopen("dijkstra.in", "r", stdin); 
	freopen("dijkstra.out", "w", stdout);
	int n, m; cin >> n >> m;
	while (m--) {
		int x, y, c; cin >> x >> y >> c;
		g.addEdge(x, y, c); }
	vector<int> dst1 = dijkstraPriorityQueue(g, 1),
				dst2 = dijkstraSet(g, vector<int>(1, 1));
	for (int i = 1; i <= n; ++i) {
		if (dst1[i] == numeric_limits<int> :: max()) {
			dst1[i] = 0; }
		if (dst2[i] == numeric_limits<int> :: max()) {
			dst2[i] = 0; }
		assert(dst1[i] == dst2[i]); 
		if (i > 1) {
			cout << dst1[i] << " "; } }
	return 0; }