SPFA, Dijkstra 代码实现

这里给出了 Bellmanford 和 SPFA 的算法思想和伪代码, 但这离具体的实现还有差距, 最短路径算法的使用频率很高, 有必要总结一下

1. SPFA 算法

算法的核心是: 松弛有效的操作必然发生在松弛前导节点成功松弛的节点上

/*
 * spfa.h
 *
 *  Created on: Apr 8, 2014
 *      Author: sangs
 */

#ifndef SPFA_H_
#define SPFA_H_
#include <queue>
using namespace std;

extern class Edge;
const int MAXNUM = 1000;
int dist[MAXNUM];
int father[MAXNUM];
int mark[MAXNUM];
vector<Edge> graph[MAXNUM];

void spfa(int st, int ed) {
	queue<int> record;
	record.push(st);
	dist[st] = 0;
	father[st] = -1;

	while(!record.empty()) {
		int u = record.front().index;
		record.pop();

		for(int i = 0; i < graph[u].size(); i ++) {
			int v = graph[u][i].index;
			if(dist[u] + graph[u][i].cost < dist[v]) {
				record.push(v);
				father[v] = u;
				dist[v] = dist[u] + graph[u][i].cost;
			}
		}
	}

	for(int i = ed; i != -1; i = father[i]) {
		mark[i] = 1;
	}
}


#endif /* SPFA_H_ */

  

2. Dijkstra 算法

代码的核心是对 visited 赋值在外面, 这样能够保证 st->ed 的路径是最短的

/*
 * Dijkstra.h
 *
 *  Created on: Apr 8, 2014
 *      Author: sangs
 */

#ifndef DIJKSTRA_H_
#define DIJKSTRA_H_

extern class Node;
const int MAXNUM = 1000;
bool visited[MAXNUM];
/*
 * Always used to calculate the shortest path/length to specific node
 */
void dijkstra(int st, int ed) {
	priority_queue<int> record;

	record.push(st);

	while(!record.empty()) {
		int u = record.top();
		
		while(!record.empty()) {
			Node v = record.top();
			record.pop();
			visited[v.index] = true;
			if(v == ed) {
				break;
			}
			
			for(int i = 0; i < graph[v.index].size(); i ++) {
				if(visited(...)) continue;
				
				record.push_back(Node(...));
			}
		}
	}
}


#endif /* DIJKSTRA_H_ */

  

2014年4月18日21:51:42

上面的 SPFA 代码有误, 需要判断一个点是否两次被加入队列

原文地址:https://www.cnblogs.com/zhouzhuo/p/3652132.html