- 唐瑾恒 的博客
最短路总结
- @ 2024-8-22 18:32:28
今天学习了最短路 , 来总结一下
最短路
- 算法,用于没有负权边的图
- 算法,用于有负权边,但没负环的图
- 算法,用于有负权环的图,一般有边数限制
T1 Dijkstra求最短路 II
solution
算法 过程
- 准备步骤 : 数组,判断是否遍历过; 数组,存从起点到每一个点的距离; 优先队列,快速找最小值
- 初始化 ,其余节点的值为
- 将 的堆顶 取到,弹出 ,此时 为 值最少,注意如果 被标记要
- 从 出发,遍历 的所有子节点,若 ,则使用 更新 这一步叫做松弛,如果 还没有被标记,入队且标记,否者不管
时间复杂度 : ,朴素算法:
code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f;
struct node{
int x , w;
bool operator <(const node &a) const &{
return a.w < w;
}
};
int n , m , s , dis[N] , vis[N];
vector<node> g[N];
void dijkstra(node s){
priority_queue<node> q;
q.push(s);
memset(dis , inf , sizeof(dis));
dis[s.x] = 0;
while(!q.empty()){
node t = q.top();
q.pop();
if(vis[t.x]) continue;
vis[t.x] = 1;
for(int i = 0 ; i < g[t.x].size() ; i ++){
node k = g[t.x][i];
if(dis[k.x] > dis[t.x] + k.w){
dis[k.x] = dis[t.x] + k.w;
if(!vis[k.x]) q.push({k.x , dis[k.x]});
}
}
}
if(dis[n] == 0x3f3f3f3f) cout << -1;
else cout << dis[n];
}
int main(){
cin >> n >> m;
for(int i = 1 ; i <= m ; i ++){
int x , y , w;
cin >> x >> y >> w;
g[x].push_back({y , w});
}
dijkstra({1 , 0});
return 0;
}
注意如果用得结构体的话要重载 运算,因为小根堆是用的