一、算法概况
dijkstra是一种稳定的求单源最短路的算法,时间复杂度O((m+n)logn)
,m表示边数,n表示点数。
二、算法过程
1.将源点以及和他相连的点加入堆
2.选出堆顶元素A(代价最小的元素),将他从堆中删除,然后调整堆
3. 处理与u相邻的,未被访问过的,满足三角不等式的顶点
1):若该点在堆里,更新距离,并调整该元素在堆中的位置。
2):若该点不在堆里,加入堆,更新堆。
4. 若取到的A为终点,结束算法;否则重复步骤2、3。
(转自百度百科)
三、代码实现
void dij(int A)
{
q.push(make_pair(0,A));//将源点的距离和源点加入堆
for(int i=1;i<=n;i++){
dis[i]=inf;//先将每个点的初始化
}
dis[A]=0;//源点到源点的距离是0
while(!q.empty()){//如果堆不为空,即并不是所有与源点联通的点都被遍历到了,我们就continue
int now=q.top().second;//取出当前堆顶的点
q.pop();//弹出堆顶元素
if(vis[now]) continue;//如果被访问过,我们就跳过
vis[now]=1;//打标记
for(int i=head[now];i;i=e[i].next){//遍历与now直接相连的点
if(dis[now]+e[i].len<dis[e[i].to]){//如果满足三角形不等式
dis[e[i].to]=dis[now]+e[i].len;//更新该点的最短路
q.push(make_pair(dis[e[i].to],e[i].to));//讲我们更新的点加入堆
}
}
}
}
四、总代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
const int maxn=1e6+7;
const int inf=1e9+7;
using namespace std;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
struct node{
int len,to,next;
}e[maxn];
int n,m,s,from,go,val,size=0,head[maxn],dis[maxn];
bool vis[maxn];
void addedge(int from,int go,int val){
size++;
e[size].to=go;
e[size].len=val;
e[size].next=head[from];
head[from]=size;
}
void dij(int A)
{
q.push(make_pair(0,A));
for(int i=1;i<=n;i++){
dis[i]=inf;
}
dis[A]=0;
while(!q.empty()){
int now=q.top().second;
q.pop();
if(vis[now]) continue;
vis[now]=1;
for(int i=head[now];i;i=e[i].next){
if(dis[now]+e[i].len<dis[e[i].to]){
dis[e[i].to]=dis[now]+e[i].len;
q.push(make_pair(dis[e[i].to],e[i].to));
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&from,&go,&val);
addedge(from,go,val);
}
dij(s);
for(int i=1;i<=n;i++){
if(dis[i]==inf){
printf("2147483647 ");
}
else{
printf("%d ",dis[i]);
}
}
return 0;
}