Dijkstrf算法

来源:互联网 发布:二次元博客源码 编辑:程序博客网 时间:2024/06/06 01:12

Dijkstrf算法

算法特性:  

优点:代码量略多,比起Ford算法稍微复杂点

缺点:效率高

优化:在Ford 的基础上进行了优化,让算法时间大大减少

实现:通过优先队列实现。

科普一条关于负圈的介绍:
负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小。

算法思想阐述:

这个算法的流程:首先我们将起点置为0,然后从起点开始更新与它相连的各个点,同时将他们排入队列中,然后在里面找一个最短的顶点

重复开始顶点的操作。


1.将顶点与其相连的点进行一个距离更新,同时将他们更新的点与其距离排入队列中。

2.找到最小的点,让那个最小的点替代刚刚那个顶点,重复1 操作 


关于这个算法的题目:http://lx.lanqiao.org/problem.page?gpid=T15


AC代码:

#include <iostream>#include<vector>#include<queue>#include<cstdio>using namespace std;struct Line{int to,cost;}; //to为终点,cost为 权数typedef pair<int ,int > P; //first为最短距离,second 是顶点的编号vector<Line>  G[20001]; //利用 Vector 的  G数组编号作为起点int d[20001];  //最短线路的记录int main(){    int p, m,temp,temp1,temp2;;//第二大错误:看题粗心,将这两个看反了//第三大错误:全程使用  Cin 连Dijkstr算法都超时了。。。 //   cin>>m>>p;//输入多少条边    scanf("%d%d",&m,&p);    for(int i=0;i<p;i++)  //读值进去    {//        cin>>temp>>temp1>>temp2;        scanf("%d%d%d",&temp,&temp1,&temp2);        Line temp3;        //下面这段话 我一开始写反了,值得注意下!!!!!!!!        temp3.to=temp1;temp3.cost=temp2;        G[temp].push_back(temp3);        //G[temp].to=temp1;        //G[temp].cost=temp2;    }    priority_queue < P,vector<P>,greater<P> > que;    fill( d,d+20001,99999 );//将距离全部置为99999,当做他们还未更新    d[1]=0;   //起点置为0    que.push(P(0,1));  //将起点放入    while(!que.empty())  //看还有没有 数据需要处理    {        P p=que.top();que.pop();//提取数据(每次提取的数据都是最短距离的点,其实这个点是一定确定了的,读者可自行进行一个验证)        int v=p.second;  //提取这个顶点编号        if(d[v]<p.first) continue; //如果这个点已经做了  最短  功能处理,那么就跳过这个点        for(int i=0;i<G[v].size();i++)//遍历这个点到它所能到的所有顶点        {            Line e=G[v][i];            if( d[e.to] > d[v] + e.cost )            {                d[e.to]=d[v]+e.cost;                que.push( P( d[e.to],e.to ) );//将处理过的点通通排入队列中            }        }    }    for(int i=2;i<=m;i++)    {        //cout<<d[i]<<endl;        printf("%d\n",d[i]);    }}


0 0