dijkstra堆优化 详解(洛谷模板题)

来源:互联网 发布:淘宝零食店铺哪里进货 编辑:程序博客网 时间:2024/06/05 16:23

一、算法概况

 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;//源点到源点的距离是0while(!q.empty()){//如果堆不为空,即并不是所有与源点联通的点都被遍历到了,我们就continueint 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;}