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();
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