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]);
}
}