Dijkstra
Posted longxue1991
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dijkstra相关的知识,希望对你有一定的参考价值。
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 500; int n, m, g[N][N], d[N]; bool st[N]; int dijkstra() { memset(d, 0x3f, sizeof d);//两点之间和1到n-1个点之间的初始值都为+oo d[1] = 0; for(int i = 0;i<n;i++) { int t = -1; for(int j = 1;j<=n;j++) if(!st[j] && (t == -1 || d[t] > d[j])) t = j; st[t] = true; for(int j = 1; j <= n;j++) d[j] = min(d[j], d[t] + g[t][j]); } if(d[n] == 0x3f3f3f3f) return -1; return d[n]; } int main() { memset(g, 0x3f, sizeof g); cin>>n>>m; for(int i = 0; i < n; i++) { int a, b, c; cin>>a>>b>>c; g[a][b] = min(g[a][b], c); } cout<<dijkstra()<<endl; }
起始点为1,1到自己的距离d[1] = 0; 走过的点就打好标记不再考虑了,st[t] = true;
任意两点之间和1到n-1个点之间的初始值都为无穷大+oo,g[]和d[]
每次向后拓展的时候都选择当前最短的边:d[t] > d[j] t = j;
若后面的点更新有更小的距离,那么就进行更新:d[j] = min(d[j], d[t] + g[t][j]);
注意Dijkstra如果有n个点的话,那么就要循环n次,也就是说,n个点没有负权的图(可以有自环和重边),通过跑n次Dijkstra一定可以跑出1到其他n-1个点的最短距离。
为什么如果有负权边不能用Dijkstra呢?因为如果有负数环的话,每跑一次距离就变小一次。。。
1≤n≤5001≤n≤500,
1≤m≤1051≤m≤105,
图中涉及边长均不超过10000。
此题点数较少,变数较多称为稠密图。上面的邻接矩阵版本是朴素的裸Dijkstra算法。
但是如果数据范围是:
数据范围
1≤n,m≤1.5×1051≤n,m≤1.5×105,
图中涉及边长均不小于0,且不超过10000。
那么就是稀疏图,如果还是用上面的邻接矩阵的话,10^5 * 10 ^ 5会爆掉。
那么就要用堆优化版本的Dijkstra算法。
以上是关于Dijkstra的主要内容,如果未能解决你的问题,请参考以下文章