Dijkstar算法
Dijkstar算法
用途:解决最短路径问题
实现方法:1.普通堆(适合稀疏图,写法简单)2.反向索引堆优化(适合稠密图,有点麻烦)
代码实现:
//普通堆
#include<bits/stdc++.h>
using namespace std;
//比较器,用来构建小根堆
struct cmp{
bool operator()(pair<int,int>&p1,pair<int,int>&p2){
return p1.second > p2.second;
}
};
void solve(){
int n,m,s;
cin >> n >> m >> s;
vector<vector<pair<int,int>>>graph(n+1);
vector<int>distances(n+1,INT_MAX);
vector<bool>visited(n+1,false);
//小根堆
priority_queue<pair<int,int>,vector<pair<int,int>>,cmp>heap;
for(int i = 0;i<m;i++){
int u,v,w;
cin >> u >> v >> w;
graph[u].push_back({v,w});
}
heap.push({s,0});
distances[s] = 0;
while(!heap.empty()){
int u = heap.top().first;
int w1 = heap.top().second;
heap.pop();
if(visited[u]){
continue;
}
visited[u] = true;
for(auto &e : graph[u]){
int v = e.first;
int w2 = e.second;
if(!visited[v] && distances[v] > w1 + w2){
distances[v] = w1 + w2;
heap.push({v,w1+w2});
}
}
}
for(int i = 1;i<=n;i++){
cout << distances[i] << " ";
}
cout << endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T = 1;
//cin >> T;
while(T--){
solve();
}
return 0;
}
优化版
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl "\n"
//链式前向星+反向索引堆优化
const int MAXN = 100010;
const int MAXM = 200010;
//建图相关
int head[MAXN];
int nxt[MAXM];
int to[MAXM];
int weight[MAXM];
int cnt;
void addEdge(int u,int v,int w){
nxt[cnt] = head[u];
head[u] = cnt;
to[cnt] = v;
weight[cnt] = w;
cnt++;
}
//建堆相关
int heap[MAXN];
int distances[MAXN];
int where[MAXN];
int heapsize;
//交换函数
void swap(int i,int j){
int tmp = heap[i];
heap[i] = heap[j];
heap[j] = tmp;
where[heap[i]] = i;
where[heap[j]] = j;
}
void build(int n ){
cnt = 1;
heapsize = 0;
fill(head + 1, head + n + 1, 0);
fill(where+1,where+n+1,-1);
fill(distances+1,distances+n+1,INT_MAX);
}
void heapInsert(int i){
while(distances[heap[i]] < distances[heap[(i-1) / 2]]){
swap(i,(i-1) / 2);
i = (i-1) / 2;
}
}
void heapify(int i){
int l = i*2+1;
while(l < heapsize){
int best = l+1 < heapsize && distances[heap[l+1]] < distances[heap[l]] ? l+1 : l;
best = distances[heap[best]] < distances[heap[i]] ? best : i;
if(best == i){
break;
}
swap(best,i);
i = best;
l = i*2 + 1;
}
}
bool isEmpty(){
return heapsize == 0;
}
int pop(){
int top = heap[0];
swap(0,--heapsize);
heapify(0);
where[top] = -2;
return top;
}
void addOrIgnore(int v,int w){
if(where[v] == -1){
heap[heapsize] = v;
distances[v] = w;
where[v] = heapsize++;
heapInsert(where[v]);
}
else if(where[v] >= 0){
distances[v] = min(distances[v],w);
heapInsert(where[v]);
}
}
void solve(){
int n,m,s;
cin >> n >> m >> s;
build(n);
distances[s] = 0;
for(int i = 0;i<m;i++){
int u,v,w;
cin >> u >> v >> w;
addEdge(u,v,w);
}
addOrIgnore(s,0);
while(!isEmpty()){
int u = pop();
for(int ne = head[u];ne > 0;ne = nxt[ne]){
int v = to[ne];
int w = weight[ne];
if(distances[v] > w+distances[u]){
addOrIgnore(v,w+distances[u]);
}
}
}
for(int i = 1;i<=n;i++){
cout << distances[i] << " ";
}
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T = 1;
//cin >> T;
while(T--){
solve();
}
return 0;
}
浙公网安备 33010602011771号