传统的dijkstra算法是维护一个集合和一个数组

在算法开始的时候,我们有一个集合X和一个数组dis. 起初将起点s加入集合,然后起点到起点的最短距离是0,dis[s] = 0;  接着我们不断的在剩下的顶点中找到一个离X最近的点v,并将该点加入到X中,然后更新dis。更新dis的原理是,比较原来到所有点到X的s的距离和新的可能通过新加入的点v产生的最短距离,取两者中较小的一个。这样当把所有的点都加入到X后就求出了所有点到s的最短距离,并保存在dis数组中。

code:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1000 + 7;

int cost[MAXN][MAXN];	// cost[u][v]表示u->v这条边的权值,不存在设为INF 
int dis[MAXN];			// 顶点从s出发的最短距离 
bool used[MAXN];		// 已经使用过的顶点 
int V;		// 顶点个数

// 求从s出发到各个顶点的最短距离
void djk(int s)
{
	memset(dis, 0x3f, sizeof(dis));
	memset(used, 0, sizeof(used));
	dis[s] = 0;		// 起点到自身的最短距离为0
	
	while(true)
	{
		int v = -1;
		for(int u = 0; u < V; u++)		// 从尚未使用过的顶点中选择一个距离最小的顶点 
			if( !used[u] && (v == -1 || dis[u] < dis[v]))	
				v = u;
		if(v == -1)		// 没有顶点可选 
			break;
		used[v] = true;
		for(int u = 0; u < V; u++)		// 更新最短距离,比较已知的最短距离和可能通过v产生的新的最短距离 
			dis[u] = min(dis[u], dis[v] + cost[v][u]);
	} 
} 

int main()
{
	
	
	
	
	return 0;
}

上面用邻接矩阵实现的dijkstra算法的复杂度是O(n^2), 下面是用优先队列和邻接表实现的dijkstra算法。复杂度O(E * log(v))。

code:

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1000 + 7;

struct Edge{
	int to, cost;
};
typedef pair<int, int> Pair;	// first 是起点到其他顶点的最短距离, second顶点的编号 

int V;
vector<Edge> G[MAXN];
int dis[MAXN];

void dijkstra(int st)
{
	priority_queue<Pair, vector<Pair>, greater(Pair)> que;	// 堆按照first从小到大的顺序取值 
	memset(dis, 0x3f, sizeof(dis));
	dis[st] = 0;
	que.push(Pair(0, st));	// 把起点放入队列
	
	while( !que.empty()) 
	{
		Pair p = que.top();
		que.pop();
		int v = p.second;
		if(dis[v] < p.first)
			continue;
		for(int i = 0; i < G[v].size(); i++)
		{
			Edge e = G[v][i];
			if(dis[e.to] > dis[v] + e.cost)
			{
				dis[e.to] = dis[v] + e.cost;
				que.push(P(dis[e.to], e.to));
			}
		} 
	}
	
}


int main()
{
	
	
	
	
	return 0;
}