dijkstra算法

对于图有两种,一种是矩阵式的方方正正的,另一种是链表式的没有固定方向的,对于第一种

cpp 复制代码
int n;
std::vector<std::vector<int>>a(n, std::vector<int>(n)),dis(n,std::vector<int>(n));
int dx[5] = { 0,1,0,-1,0 };
int dy[5] = { 0,0,1,0,-1 };
using  PII= std::pair<int, int>;
PII st,end;
struct node {
	int x, y, dis;
	bool operator>(const node& other)const {
		return dis > other.dis;
	}
};
int dijkstra() {
	std::priority_queue<node>q;
	q.push({ st.first, st.second, 0 });
	dis[st.first][st.second] = 0;
	while (q.empty()) {
		node t = q.top();
		q.pop();
		if (t.x == end.first && t.y == end.second)return t.dis;
		for (int i = 1; i <=4; i++) {
			int nx = t.x + dx[i];
			int ny = t.y + dy[i];
			if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
				int ndis = t.dis + a[nx][ny];
				if (ndis < dis[nx][ny]) {
					dis[nx][ny] = ndis;
					q.push({ nx,ny,ndis });
				}
			}
		}
	}
	return -1;
}
int main() {
	//输入获取起点终点和地图
	dijkstra();
	//输出结果
}

本质上是个广搜,和第二种相同的方面有以下几点,我们需要一个dis数组来存每个节点的搜索值,用于储存当前节点的最优值,本质框架不变,使用优先队列作为主要结构,但是这种判到终点的就是返回,且需要判断是否出界.还需要定义一个辅助方向数组.

来看看第二种

我们先来看有向图的情况

【模板】单源最短路径(标准版) - 洛谷

cpp 复制代码
constexpr int MaxM = 500010;
constexpr int MaxN = 100010;
struct edge {
	int to, dis, next;
};
edge e[MaxM];
int head[MaxN], dis[MaxN], cnt;
bool vis[MaxN];
int n, m, s;
inline void add_edge(int u, int v, int d) {
	cnt++;
	e[cnt].dis = d;
	e[cnt].to = v;
	e[cnt].next = head[u];
	head[u] = cnt;
}
struct node {
	int dis;
	int pos;
	bool operator<(const node& x)const {
		return x.dis < dis;
	}
};
std::priority_queue<node>q;
inline void dijkstra() {
	dis[s] = 0;
	q.push({ 0, s });
	while (!q.empty()) {
		node tmp = q.top();
		q.pop();
		int x = tmp.pos, d = tmp.dis;
		if (vis[x])continue;
		vis[x] = 1;
		for (int i = head[x]; i; i = e[i].next) {
			int y = e[i].to;
			if (dis[y] > dis[x] + e[i].dis) {
				dis[y] = dis[x] + e[i].dis;
				if (!vis[y]) {
					q.push({ dis[y],y });
				}
			}
		}
	}
}
int main() {
	std::cin >> n >> m >> s;
	for (int i = 1; i <= n; i++)dis[i] = 0x7fffffff;
	for (register int i = 0; i < m; i++) {
		register int u, v, d;
		std::cin >> u >> v >> d;
		add_edge(u, v, d);
	}
	dijkstra();
	for (int i = 1; i <= n; i++) {
		std::cout << dis[i]<<' ';
	}
	return 0;
}

有向图我们只需要正着存一次,并把dis数组初始化为INT_MAX.

而对于无向图,我们需要存两次,并把边数扩大为原来的两倍,相当于一去一回这个样子.

cpp 复制代码
constexpr int MAXM = 12410; // 修改为无向边转化后的边数的两倍
inline void add_edge(int u, int v, int d) {
	cnt++;
	// 第一条有向边:from u to v
	e[cnt].to = v;
	e[cnt].dis = d;
	e[cnt].next = h[u];
	h[u] = cnt;

	// 第二条有向边:from v to u
	cnt++;
	e[cnt].to = u;
	e[cnt].dis = d;
	e[cnt].next = h[v];
	h[v] = cnt;
}
相关推荐
小豆庄1 天前
本地视频脱敏的追踪系统踩坑——车牌过滤、转场误判与ID冲突排查
人工智能·算法·目标检测·音视频·视频·敏捷流程·纹理贴图
忆挽篱笙歌1 天前
进程替换函数与shenll命令行解释器
前端·javascript·算法
YukiRinLL1 天前
字符串存储与 BF、KMP 匹配算法
数据结构·算法
小超人诞生日记1 天前
Linux:环境变量 & 进程虚拟地址空间
linux·算法
小白起 v1 天前
【算法学习 · 01】深入理解大 O 表示法:从「能跑就行」到「专业评估」算法性能
算法
梦帮科技1 天前
脑机接口(BCI)与神经系统安全:EEG 神经电信号欺骗注入、神经闭环解码算法与生物黑客反制
算法·安全
老徐聊GEO1 天前
把“安徽“写进题面之后:多平台AI推荐名单的区域扰动测量(2026)
前端·人工智能·算法·geo优化
人工智能培训1 天前
具身智能:让人工智能拥有物理世界感知能力
大数据·人工智能·学习·算法·机器学习
果壳science1 天前
张祥前最新研究成果登上SCI期刊!
笔记·嵌入式硬件·算法·硬件工程·几何学
Rabitebla1 天前
【Linux 底层原理】工具篇(一):掌握 Ubuntu apt,让软件安装与管理更简单
linux·笔记·算法·ubuntu