Dijkstra算法——最短路径

´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("\n");
    return 0;
 } 

 

posted @ 2017-01-25 16:27  Mr.9Pounds15Pence  阅读(180)  评论(0编辑  收藏  举报