迪杰斯特拉的优化算法采用堆优化,优化之前是花费 O ( n ) O(n) O(n)时间来查找未最优点里面距离点1最小的点。现在使用堆优化,直接花费 O ( 1 ) O(1) O(1)时间就完事儿了。
堆里面存储 p a i r < i n t , i n t > pair<int,int> pair<int,int>类型,前面int
存储距离first
,后面存储顶点second
。默认排序按照pair
的第一个int
进行排序。小的存储在堆顶。
然后取出来顶点ver
和distance
,沿着ver关联的所有出边,查找是否存在通过ver
的点到点j
的距离使得d[j]
更短。
st数组表示标识st【j】,j这个点是否已经是最优的最短距离!
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>using namespace std;typedef pair<int, int> PII;const int N = 1e6 + 10;int n, m;
int h[N], w[N], e[N], ne[N], idx;
int dist[N];
bool st[N];void add(int a, int b, int c)
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}int dijkstra()
{memset(dist, 0x3f, sizeof dist);dist[1] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});while (heap.size()){auto t = heap.top();heap.pop();int ver = t.second, distance = t.first;if (st[ver]) continue;st[ver] = true;for (int i = h[ver]; i != -1; i = ne[i]){int j = e[i];if (dist[j] > dist[ver] + w[i]){dist[j] = dist[ver] + w[i];heap.push({dist[j], j});}}}if (dist[n] == 0x3f3f3f3f) return -1;return dist[n];
}int main()
{scanf("%d%d", &n, &m);memset(h, -1, sizeof h);while (m -- ){int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c);}printf("%d\n", dijkstra());return 0;
}