dijkstra(学习笔记)(25.10.13)

dijkstra(学习笔记)

dijkstra(练习笔记)

概述

  1. 用于单源最短路径求解
  2. 非负权图
  3. 使用贪心理念,先把最小的跑完,有两种做法,一个n^2一个m log m,第二种使用堆优化先跑最小的,刚好不需要n方遍历
  4. 其实堆优化理念和BFS(优先队列优化版)很像

堆优化实现

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5*5+10;
const int M = 1e4+10;
int n, m, s;

//建图
int cnt, h[M];
struct Node {
 int to, next, w;
}e[2*N];
void add(int u, int v, int w) {
 e[++cnt].to = v;
 e[cnt].next = h[u];
 e[cnt].w = w;
 h[u] = cnt;
}

//定义一个重构的结构体
struct node {
 //dis表示到u点的最小值
 int dis, u;
 //返回F/T表示当下的dis与另一个数比较,const表示不会改变当前的数
 //声明禁止修改,但是可以访问,末尾的const是声明前面函数的成员元素禁止修改
 //然后是在这个重构函数里进行比较大小的,直接用dis和新node下比较
 //const对象是不能调用非const的成员函数的
 bool operator<(const node& a) const { return dis > a.dis; }
};
//Dijkstra(总点数,s为起点)
//定义dis和vis分别表示为最短路和是否为最值最小
int dis[M], vis[M];
//定义一个优先队列做优化
priority_queue<node> q;
void Dij(int n, int s) {
 memset(vis, 0, sizeof(vis));
 memset(dis, 0x3f, sizeof(dis));
 dis[s] = 0;//当前最小值是0
 q.push({0,s});
 while (!q.empty()) {
     int u = q.top().u;
     q.pop();
     //因为用了堆优化,没必要去做n^2模拟去找那个最小未确定节点
     //每次去找最小未确定节点,最后可以得到最好的优化
     vis[u] = 1;
     for (int i = h[u]; i!=0; i = e[i].next) {
         int v = e[i].to, w = e[i].w;
         //去寻找更小的边去更新
         if (dis[v]>dis[u] + w) {
             dis[v] = dis[u] + w;
             q.push({dis[v], v});
         }
     }
 }
}

int main() {
 cin >> n >> m >> s;
 for (int i=1; i<=m; i++) {
     int u, v, w;
     cin >> u >> v >> w;
     add(u, v, w);
     // add(v, u, w);
 }
 Dij(n, s);
 for (int i=1; i<=n; i++) {
     if (dis[i]==0x3f3f3f3f) {
         cout<<2147483647<<" ";
         continue;
     }
     cout << dis[i] << " ";
 }
 return 0;
}

其实还顺便学了一下const和重构运算符

posted @ 2025-10-13 21:30  Yuriha  阅读(0)  评论(0)    收藏  举报