Dijkstra算法图文详解(转)

本文转载自:https://blog.csdn.net/lbperfect123/article/details/84281300

Dijkstra算法

Dijkstra算法算是贪心思想实现的,首先把起点到所有点的距离存下来找个最短的,然后松弛一次再找出最短的,所谓的松弛操作就是,遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。

问题引入:

指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”。例如求下图中的1号顶点到2、3、4、5、6号顶点的最短路径。
Dijkstra算法图文详解(转)_第1张图片
Dijkstra算法图文详解(转)_第2张图片Dijkstra算法图文详解(转)_第3张图片
Dijkstra算法图文详解(转)_第4张图片
Dijkstra算法图文详解(转)_第5张图片
Dijkstra算法图文详解(转)_第6张图片
Dijkstra算法图文详解(转)_第7张图片
在这里插入图片描述
下面我们来模拟一下:
Dijkstra算法图文详解(转)_第8张图片
Dijkstra算法图文详解(转)_第9张图片
代码实现:

#include 
#include 
using namespace std;
const int INF = 0x3f3f3f3f, N = 205;

int ma[N][N];
int dis[N];
bool vis[N];
int n, m, st, ed;

void init()
{
	// 初始化ma数组
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			ma[i][j] = (i == j ? 0 : INF);
}

void Dijk()
{
	for (int i = 0; i < n - 1; i++){
		int minv = INF, k;  // k用来存储最小的且没被松弛过的城市
		for (int j = 0; j < n; j++){
			if (minv > dis[j] && !vis[j]){
				minv = dis[j];
				k = j;
			}
		}
		vis[k] = 1;
		for (int h = 0; h < n; h++)
			dis[h] = min(dis[h], dis[k] + ma[k][h]);
	}	
}

int main(void)
{
	int a, b, c;
	while (cin >> n >> m){
		// 初始化ma数组 
		init();
		for (int i = 0; i < m; i++){
			cin >> a >> b >> c;
			if (ma[a][b] > c)
				ma[a][b] = ma[b][a] = c;
		}
		// 输入起点和终点 
		cin >> st >> ed;
		// 初始化dis数组
		for (int i = 0; i < n; i++)
			dis[i] = ma[st][i];
		// 初始化vis数组
		memset(vis, 0, sizeof vis);
		vis[st] = 1;
		
		Dijk();
		cout << (dis[ed] == INF ? -1 : dis[ed]) << endl;
	}
	return 0;
}

你可能感兴趣的:(#,专题四,最短路练习,#,模板合集)