Dijkstra演算法(c++版)
阿新 • • 發佈:2019-02-08
最短路徑(DP的應用)
單源最短路徑,不允許出現負環
核心思想:更新估算距離,鬆弛
時間複雜度與採用的資料結構有關,標準的dijkstra應該是用堆實現的。
Array O()
Binary heap O()
Fibonacci heap O()
如果對於所有的邊權值均為1,那麼Dijkstra演算法可以用BFS實現
使用FIFO佇列代替Priority佇列,其時間複雜度為O()
陣列實現:
#include <iostream> using namespace std; void dijkstra(); int e[10][10]; int vis[10]; int dis[10]; int n, m; int min1 = 99999999; int u = 0; int main() { cin >> n >> m; // 初始化鄰接表 for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (i == j) { e[i][j] = 0; } else { e[i][j] = 99999999; } } } // 填充資料 for (int i = 1; i <= m; i++) { int a, b, c; cin >> a >> b >> c; e[a][b] = c; } for (int i = 1; i <= n; i++) { dis[i] = e[1][i]; } vis[1] = 1; dijkstra(); for (int i = 1; i <= n; i++) { cout << dis[i]; } system("pause"); return 0; } void dijkstra() { for (int i = 1; i <= n - 1; i++) { min1 = 99999999; // 尋找權值最小的點u for (int j = 1; j <= n; j++) { if (vis[j] == 0 && dis[j] < min1) { min1 = dis[j]; u = j; } } vis[u] = 1; for (int v = 1; v <= n; v++) { // 對於每個u可達的v來說 if (e[u][v] < 99999999) { // 如果當前的dis[v]不滿足三角形不等式,那麼進行鬆弛操作 if (dis[v] > dis[u] + e[u][v]) { dis[v] = dis[u] + e[u][v]; } } } } }
堆實現
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> using namespace std; const int Ni = 10000; const int INF = 1 << 27; struct node { int point, value; // 構造 node(int a, int b) { point = a; value = b; } // 過載<操作符 bool operator<(const node &a) const { // 對小於運算子進行過載,如果兩個值相等,那麼繼續判斷point,如果不等,則返回false if (value == a.value) { return point < a.point; } else { return value > a.value; } } }; vector<node> e[Ni]; int dis[Ni], n; priority_queue<node> q; void dijkstra(); int main() { int a, b, c, m; scanf("%d%d", &n, &m); while (m--) { scanf("%d%d%d", &a, &b, &c); e[a].push_back(node(b, c)); e[b].push_back(node(a, c)); } // for (int i = 0; i <= n; i++) // { // dis[i] = INF; // } memset(dis, 0x3f, sizeof(dis)); dis[1] = 0; // 優先佇列,隊頭元素最大,但是如果型別為struct需要過載<運算子 q.push(node(1, dis[1])); dijkstra(); for (int i = 1; i <= n; i++) { printf("%d ", dis[i]); } system("pause"); return 0; } void dijkstra() { while (!q.empty()) { node x = q.top(); q.pop(); for (int i = 0; i < e[x.point].size(); i++) { node y = e[x.point][i]; if (dis[y.point] > dis[x.point] + y.value) { dis[y.point] = dis[x.point] + y.value; q.push(node(y.point, dis[y.point])); } } } }