迪杰斯特拉dijkstra算法总结

总结分析

  1. 总共分成两步
    • 第一步:寻找一个这次要确认的结点
    • 第二步:利用这次确认的结点,对所有未确认结点到源点的距离进行松弛
      • 松弛:比如原本记录源点到结点4的距离为6,这次确认了结点2,源点到结点2距离为2,结点2到结点4的距离为3,总距离为5,即可更新结点4到源点的距离
  2. 二维数组G,记录结点间的距离;数组confirmed,记录结点是否被确认,初始化为false;数组dis,记录结点到源点的距离,初始化为inf(无限大)
  3. 进入dijkstra算法前先确定源点source,我们就可以确认源点到源点的距离dis[source]=0
  4. 第一个for循环,只需要确认n-1个结点即可,因为确定第n-1个结点后,会更新第n个结点到源点的距离
  5. 第二个for循环,寻找这次要确认的结点,要满足两个条件
    • 该结点未被确认
    • 该结点到源点的距离是目前已知所有距离中最小的
  6. 第三个for循环,利用这次确认的结点,对所有未确认的结点到源点的距离进行松弛

注意

  • 时间复杂度O(n²)
  • 单源最短路径
  • 解决不了负权图,有可能出错

题目

从0点出发,寻找到达每一个结点的最短路径(单源最短路径问题

代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define n 7
#define inf 233
vector<vector<int>> G(n, vector<int>(n,inf));
vector<int> dijkstra(vector<vector<int>>, int source) {
	vector<bool> confirmed(n, false);
	vector<int> dis(n, inf);
	dis[source] = 0;
	for (int i = 0; i < n - 1; i++) {
		int curr=-1;
		for (int j = 0; j < n; j++) {
			if (!confirmed[j] && (curr == -1 || dis[curr] > dis[j])) curr = j;
		}
		confirmed[curr] = true;
		for (int j = 0; j < n; j++) {
			if(!confirmed[j]&&dis[j]>G[curr][j]+dis[curr]) dis[j] = G[curr][j]+dis[curr];
		}
	}
	return dis;
}

int main() {
	G[0][2] = 2;
	G[0][1] = 5;
	G[1][3] = 1;
	G[1][4] = 6;
	G[1][0] = 5;
	G[2][3] = 6;
	G[2][5] = 8;
	G[2][0] = 2;
	G[3][2] = 6;
	G[3][1] = 1;
	G[3][4] = 1;
	G[3][5] = 2;
	G[4][1] = 6;
	G[4][3] = 1;
	G[4][6] = 7;
	G[5][2] = 8;
	G[5][3] = 2;
	G[5][6] = 3;
	G[6][4] = 7;
	G[6][5] = 3;

	vector<int> ans = dijkstra(G, 0);
	for (auto a : ans) cout << a << " ";
	cout << endl;

	return 0;
}

结果

posted @ 2020-10-11 19:09  肥斯大只仔  阅读(986)  评论(0编辑  收藏  举报