Блог пользователя n8118

Автор n8118, история, 11 лет назад, По-английски

I have learnt Dijkstra's recently and couldn't implement it effectively. Can some one post your Dijkstra's algo implementation in (c or c++) using stl's. I will use it as reference to implement my code. Thanks in advance..

  • Проголосовать: нравится
  • +1
  • Проголосовать: не нравится

»
11 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Hello, You can try this question : EZDIJKST, it's a direct implementation of the algorithm. You can refer My Solution which uses STL set for reference.

»
11 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

This is my typical implementation of Dijkstra using C++11 and priority_queue: Dijkstra (this code finds the shortest path from node 1 to all other nodes)

»
8 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Hello!

First of all, I would suggest you to write your own version of the code (for testing you have 20C — Dijkstra? problem here on Codeforces), because you will learn how the algorithm works and how to use it. However I will give you my code :). Keep in mind you can find more versions of Dijkstra on geekforgeeks, e-maxx, youtube, ...

Here is my Dijkstra template: https://github.com/Sprdalo/Compete/blob/master/dijkstra.sublime-snippet

To see how to use it go to my submit for this problem which is given here.

»
7 лет назад, скрыть # |
 
Проголосовать: нравится -8 Проголосовать: не нравится

Checked with C. Dijkstra?.

#include <bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" is "<<endl

using ll = long long;

#define x first
#define y second

template <typename T>
struct Dijkstra {

	int node,edge;
	vector< vector< pair<int,T> > > adj;
	vector< T > level;
	vector<int> parent;

	Dijkstra(int _node, int _edge) : node(_node), edge(_edge) {
		vector<int>(node+1).swap(parent);
		vector<T>(node+1, numeric_limits<T>::max()).swap(level);
		vector< vector< pair<int,T> > > (node+1).swap(adj);
	}

	void add_edge(int u, int v, T w) {
		adj[u].push_back({v,w});
		adj[v].push_back({u,w});
	}

	void traverse(int src) {

		level[src] = 0;
		set< pair<T,int> > s {{0,src}};
		parent[src] = -1;

		while(not s.empty()) {
			auto it = *s.begin();
			int cur_node = it.y;
			T cur_level = it.x;
			s.erase(s.begin());

			for(auto u : adj[cur_node]) {
				if(level[u.x] - u.y > cur_level) {
					level[u.x] = cur_level + u.y;
					parent[u.x] = cur_node; 
					s.insert({level[u.x],u.x});
				}
			}
		}
	}

	void print_path(int x) {

		if(level[x] == numeric_limits<T>::max()) {
			cout<<"-1\n";
			return;
		}

		if(x == -1){
			return;
		}

		print_path(parent[x]);
		cout<<x<<" ";

	}

};


int main(int argc, char const *argv[])
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);


	int node,edge;
	cin>>node>>edge;

	Dijkstra<ll> d(node,edge);


	while(edge--){
		int x,y;
		ll w;
		cin>>x>>y>>w;
		d.add_edge(x,y,w);
	}

	d.traverse(1);
	d.print_path(node);

	return 0;
}
»
6 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

https://github.com/okwedook/olymp/blob/master/Dijkstra.cpp

This is an actually fast and memory efficient (and also veeery short) implementation. It uses a few template features I use, but you can look at template.cpp in the same repo.

»
6 лет назад, скрыть # |
Rev. 3  
Проголосовать: нравится 0 Проголосовать: не нравится
Dijkstra - priority_queue implementation
Dijkstra - Set implementation
SPFA - Queue implementation
»
6 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится -15 Проголосовать: не нравится
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define f first
#define s second
#define mp make_pair
#define inf 999999999999
using namespace std;
ll n,m;
ll dist[1000009],par[1000009];

void dij(vector<pair<ll,ll> > graph[])
{
	ll i;
	set < pair<ll,ll> > s;
	s.insert(mp(0,1));
	
	for(i=1;i<=n;i++)
	{
		dist[i]=inf;
	}
	dist[1]=0;
	par[1]=0;
	while(!s.empty())
	{
		set <pair<ll,ll> > :: iterator itr;
		itr=s.begin();	
		ll u=itr->s;
		s.erase(s.begin()); 
		for(i=0;i<graph[u].size();i++)
		{
			ll wn=graph[u][i].f;
			ll v=graph[u][i].s;
			
			if(dist[v]>dist[u]+wn)
			{
				if(dist[v]!=inf)
				{
					s.erase(s.find(mp(dist[v],v)));
				}
				dist[v]=dist[u]+wn;
				s.insert(mp(dist[v],v));
				par[v]=u;
			}
			
		}
	}
	
	
}
main()
{
	ios_base::sync_with_stdio(false); 
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	ll i;
	vector<pair<ll,ll> > graph[n+1];
	for(i=1;i<=m;i++)
	{
		ll a,b,w;
		cin>>a>>b>>w;
		graph[a].pb(mp(w,b));
		graph[b].pb(mp(w,a));
	}
	dij(graph);
	if(dist[n]==inf)
		cout<<"-1";
	else
	{
	vector<ll> v;
	i=n;
	v.pb(i);
	while(i!=1)
	{
		v.pb(par[i]);
		i=par[i];	
	}
	for(i=v.size()-1;i>=0;i--)
		cout<<v[i]<<" ";
	cout<<endl<<dist[n];
}
	
}
	

»
6 лет назад, скрыть # |
Rev. 4  
Проголосовать: нравится +3 Проголосовать: не нравится

Dijkstra's (CP-Algorithms)

Take a look at the priority queue based implementation. You could probably modify it a bit to make it shorter to code.

Dijkstra's With Path Printing

»
6 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I use this implementation. It is from this book.

for (int i = 1; i <= n; i++) distance[i] = INF;
distance[x] = 0;
q.push({0,x});
while (!q.empty()) {
    int a = q.top().second; q.pop();
    if (processed[a]) continue;
    processed[a] = true;
    for (auto u : adj[a]) {
        int b = u.first, w = u.second;
        if (distance[a]+w < distance[b]) {
            distance[b] = distance[a]+w;
            q.push({-distance[b],b});
        }
    }
}
»
6 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
I think it will help you
»
4 года назад, скрыть # |
 
Проголосовать: нравится -13 Проголосовать: не нравится

I tried to submit my code of dijkstra's on codeforces C. Dijkstra? but I am running into a weird error. I have detailed my question here on stackoverflow: https://stackoverflow.com/questions/71748407/how-can-a-node-in-dijkstra-be-relaxed-after-it-has-already-been-processed?noredirect=1#comment126796300_71748407

basically, the question is, if I relax a node v, then that means there is no way that node has been processed (i.e. it hasn't been popped from the heap and we haven't found the min dist to that node yet). This means that processed[v] == true should never evaluate to true when we are relaxing the node v. But it does in the testcases of codeforces question