“二叉堆优化基于贪心的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;
}