Dijkstra 最短路
非负权最短路,优先队列取最近未确定点
前置内容
正文
// Dijkstra:非负权最短路
// 贪心选最近未确定点
// 用优先队列取最小距离
// 邻接表建图(见 cspj-adj)
#include <cstdio>
#include <queue>
using namespace std;
int h[10005], nxt[200005];
int to[200005], w[200005];
int cnt = 0, n, m, dis[10005];
bool vis[10005];
// 加边(带权)
void add(int u, int v, int c) {
nxt[++cnt] = h[u];
h[u] = cnt;
to[cnt] = v;
w[cnt] = c;
}
// 小根堆:存(距离, 点)
priority_queue<pair<int, int>,
vector<pair<int, int> >,
greater<pair<int, int> > > pq;
void dij(int s) {
// 距离初为无穷大
for (int i = 1; i <= n; i++)
dis[i] = 1e9;
dis[s] = 0;
pq.push({0, s});
while (!pq.empty()) {
int u = pq.top().second; pq.pop();
// 已确定过则跳过
if (vis[u]) continue;
vis[u] = 1;
// 松弛所有出边
for (int e = h[u]; e; e = nxt[e])
// 更近则更新并入队
if (dis[u] + w[e]
< dis[to[e]]) {
dis[to[e]] = dis[u]
+ w[e];
pq.push({dis[to[e]],
to[e]});
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
add(u, v, c);
}
dij(1);
printf("%d", dis[n]);
return 0;
}
CSP-J · 编程模板的其它内容
- 输出一句话
- 两数求和
- 矩形周长与面积
- 圆的面积
- 三数求平均值
- 摄氏转华氏
- 三位数各位拆分
- 简单本息
- 交换两个数
- 圆的周长与面积
- 三角形面积
- 梯形面积
- 长方体体积
- 英里转公里
- 总秒数换算分秒
- 商品总价与找零
- 存储单位与数据规模
- 字符编码与 ASCII
- 位运算
- 原码反码补码
- 进制转换
- 数据范围与溢出
- 时间复杂度估算
- 初赛程序阅读技巧
- 变量与数据类型
- 输入输出
- 运算符与表达式
- 分支 if/switch
- 基础循环
- 数组遍历
- 字符数组与 string
- 函数与参数传递
- 全局变量与局部变量
- 类型转换与取整
- 文件读写 freopen
- 结构体
- 指针与引用
- vector 动态数组
- string 常用操作
- algorithm 常用算法
- pair 与自定义排序
- stack 栈
- queue 队列
- priority_queue 优先队列
- set 集合
- map 映射
- lower_bound 二分
- next_permutation 全排列
- 枚举法
- 模拟
- 递归求阶乘
- 求素数
- 埃氏筛素数表
- 前缀和
- 差分
- 冒泡排序
- 插入排序
- 快速排序
- 归并排序
- 双指针