dijkstra 算法优先队列实现
基于优先队列的算法实现其实很简单,
首先,我们要清楚dijkstra 算法的核心思想:
n次查找:
1.每次查找距离起点s最近的 且未访问的顶点 u ,dist[u] 表示距离起点的最近的点的距离
2.for(从 u 出发能到达的所有的顶点v):
if(以 u 为中介点 能够使得 s 到顶点v的最短距离d[v]更优){
优化d[v]
}
而优先队列在这里做的一点就是,能够在查找最小未访问的点时,能够快速找到,使得 第一步能够以 logn的复杂度找到最小未访问点u
#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
struct node{
int to,cost,rec;//目标,开销,反相边
node(){}
node(int to,int cost,int rec):to(to),cost(cost),rec(rec){}
};
const int MAXN = 10000;
vector<node> map_[MAXN];
const int INF = 0x3f3f3f3f;
void add_edge(int a,int b,int cost){
map_[a].push_back(node(b,cost,map_[b].size()));
map_[b].push_back(node(a,cost,map_[a].size()-1));
}
int dist[MAXN];
int N,M,start;
struct qnode{
int len;
int to;
qnode(){}
qnode(int to,int len):to(to),len(len){}
bool operator <(const qnode & b) const{
return len>b.len;
}
};
void dijkstra(int start){
fill(dist,dist+N,INF);
dist[start] = 0;
qnode temp(start,0);
priority_queue<qnode> que;
que.push(temp);
while(!que.empty()){
qnode temp = que.top(); que.pop();
if(dist[temp.to] != temp.len) continue;
for(int i=0;i<map_[temp.to].size();i++){
node nnode = map_[temp.to][i];
if(nnode.cost + dist[temp.to] < dist[nnode.to]){
dist[nnode.to] = nnode.cost + dist[temp.to];
que.push(qnode(nnode.to,dist[nnode.to]));
}
}
}
}
int main(){
scanf("%d%d%d",&N,&M,&start);
for(int i=1;i<=M;i++){
int a,b,cost;
scanf("%d%d%d",&a,&b,&cost);
add_edge(a,b,cost);
}
dijkstra(start);
for(int i=0;i<N;i++){
printf("%d ",dist[i]);
}
printf("\n");
return 0;
}
input:
6 8 0 // 6个顶点, 8条边, 0号为七点
0 1 1 // 边 0-> 1 权为 1 下同
0 3 4
0 4 4
1 3 2
2 5 1
3 2 2
3 4 3
4 5 3
output:
0 1 5 3 4 6