Dijkstra模板(优先队列)

“二叉堆优化基于贪心的Dijkstra算法”和“优先队列优化基于BFS的SPFA算法”殊途同归,都可以得到非负权图上 O(mlogn) O ( m l o g n ) 的单源最短路径算法。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const double eps=1e-8;
const int MAXN=1005;
const int INF=0x3f3f3f3f;
int pre[MAXN],dist[MAXN];
int cnt[MAXN],a[MAXN],peo[MAXN];
bool vis[MAXN];

struct Edge{
    int v,w;
    Edge(int _v=0,int _w=0):v(_v),w(_w){}
};
vector<Edge> g[MAXN];

struct QNode{
    int v,d;
    QNode(int _v=0,int _d=0):v(_v),d(_d){}
    bool operator < (const QNode &rhs) const{
        return d>rhs.d;
    }
};

void Init(int n){
    for(int i=0;i<=n;i++){
        g[i].clear();
        cnt[i]=0;peo[i]=0;
        pre[i]=-1;dist[i]=INF;
        vis[i]=false;
    }
}

int Dijkstra(int s){
    priority_queue<QNode> q;
    while(!q.empty()) q.pop();
    dist[s]=0;cnt[s]=1;peo[s]=a[s];
    q.push(QNode(s,0));
    QNode frt;
    while(!q.empty()){
        frt=q.top();
        q.pop();
        int u=frt.v;
        if(vis[u]) continue;
        vis[u]=true;
        int sz=g[u].size();
        for(int i=0;i<sz;i++){
            int v=g[u][i].v;
            int cost=g[u][i].w;
            if(dist[v]>dist[u]+cost){
                dist[v]=dist[u]+cost;
                pre[v]=u;
                cnt[v]=cnt[u];
                peo[v]=peo[u]+a[v];
                q.push(QNode(v,dist[v]));
            }else if(dist[v]==dist[u]+cost){
                if(peo[v]<peo[u]+a[v]){
                    pre[v]=u;
                    peo[v]=peo[u]+a[v];
                }
                cnt[v]+=cnt[u];
            }
        }
    }
}

void dfs(int s,int u){
    if(u==s) printf("%d",s);
    else{
        dfs(s,pre[u]);
        printf(" %d",u);
    }
}

int main(){
    int n,m,s,d;
    while(scanf("%d%d%d%d",&n,&m,&s,&d)!=EOF){
        Init(n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        int u,v,w;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            g[u].push_back(Edge(v,w));
            g[v].push_back(Edge(u,w));
        }
        Dijkstra(s);
        printf("%d %d\n",cnt[d],peo[d]);
        dfs(s,d);
        printf("\n");
    }
    return 0;
}
///使用优先队列Dijkstra算法
///复杂度O(ElogV)
///注意初始化
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<fstream>
using namespace std;
typedef pair<int,int> PII;
const int MAXN=1e4+5;
const int INF=0x3f3f3f3f;
bool vis[MAXN];
int dist[MAXN],head[MAXN],tot;
int pre[MAXN];

struct Edge
{
    int from,to,cost,nxt;
    Edge(){}
    Edge(int _from,int _to,int _cost):from(_from),to(_to),cost(_cost){}
}e[MAXN*2];

void addedge(int u,int v,int w)
{
    e[tot].from=u;e[tot].to=v;e[tot].cost=w;
    e[tot].nxt=head[u];head[u]=tot++;
}

struct qnode
{
    int c,v;
    qnode(int _c=0,int _v=0):c(_c),v(_v){}
    bool operator < (const qnode &rhs) const {return c>rhs.c;}
};

void Dijkstra(int n,int st)//点的编号从1开始
{
    memset(vis,false,sizeof(vis));
    for(int i=0;i<=n;i++) dist[i]=INF;
    priority_queue<qnode> pq;
    while(!pq.empty()) pq.pop();
    dist[st]=0;
    pq.push(qnode(0,st));
    qnode frt;
    while(!pq.empty())
    {
        frt=pq.top(); pq.pop();
        int u=frt.v;
        if(vis[u]) continue;
        vis[u]=true;
        for(int i=head[u];i!=-1;i=e[i].nxt)
        {
            int to=e[i].to;
            int cost=e[i].cost;
            if(dist[to]>dist[u]+cost)
            {
                dist[to]=dist[u]+cost;
                pre[to]=u;
                pq.push(qnode(dist[to],to));
            }
        }
    }
}

int main()
{
    int vN,eN;
    while(scanf("%d%d",&vN,&eN)!=EOF)
    {
        if(vN==0&&eN==0) break;
        tot=0;memset(head,-1,sizeof(head));
        int u,v,w;
        for(int i=1;i<=eN;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);addedge(v,u,w);
        }
        int st,ed;
        scanf("%d%d",&st,&ed);
        //if(st==ed) {printf("0\n");continue;}
        Dijkstra(vN,st);
// for(int i=0;i<=vN-1;i++)
// printf("%d ",dist[i]);
// printf("\n");
// for(int i=0;i<=vN-1;i++)
// printf("%d ",pre[i]);
// printf("\n");
        if(dist[ed]!=INF)  printf("%d\n",dist[ed]);
        else printf("-1\n");
    }
    return 0;
}
    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/algzjh/article/details/77607242
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞