´Dijkstra算法是用于求解正权图当中的单源(出发点唯一)的最短路径问题。
´下面,我们均假设我们的出发点为1.
´清除所有点的标记,并给每个点设置一个从源点出发的距离,最初d[1]=0,其余d[i]=+oo。
´循环n次
´在所有未标记的点当中选择距离最小的节点v
´通过从v出发的所有边(v,y),更新所有的d[y]=min(d[y],d[v]+w(v,y))(松弛)
´循环n次之后d数组记录的就是从源点出发的最短路径
´该算法的原理主要是基于没有负边这一点,也就是说每次选择的d最小的节点,必然已经达到最优情况,而不可能被其它点更新
´对于该算法的实现,我们同样可以通过一个优先队列(或者堆)去维护求出每个时间里距离最小的节点
#include <bits/stdc++.h> using namespace std; const int maxn=100000+15; const int maxm=100000+15; const int oo=100000000; struct Edge { int x,y,z,next; Edge(int x=0,int y=0,int z=0,int next=0):x(x),y(y),z(z),next(next) {} }edge[maxm]; int n,m; int sumedge,head[maxn]; int dis[maxn]; int ins(int x,int y,int z) { edge[++sumedge]=Edge(x,y,z,head[x]); return head[x]=sumedge; } struct Node { int x,v; Node(int x=0,int v=0):x(x),v(v){} }; const bool operator < (const Node &a,const Node &b) { return a.v<b.v; } priority_queue <Node> que; int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); ins(x,y,z); } for (int i=2;i<=n;i++) dis[i]=-oo; que.push(Node(1,oo)); for (int i=1;i<=n;i++) { Node temp=que.top(); for (;dis[temp.x]!=temp.v;que.pop(),temp=que.top()); que.pop(); for (int u=head[temp.x];u;u=edge[u].next) if (dis[edge[u].y]<min(temp.v,edge[u].z)) { dis[edge[u].y]=min(temp.v,edge[u].z); que.push(Node(edge[u].y,dis[edge[u].y])); } } for (int i=1;i<=n;i++) printf("%d ",dis[i]); printf(" "); return 0; }