杭电1874——Dijkstra(迪杰斯特拉)最短路径

杭电1874——Dijkstra(迪杰斯特拉)最短路径

原题传送门
迪杰斯特拉模板可以过,代码借鉴的是一个大佬的CSDN博客,不过后来整丢了,我的代码是我一个字母一个字母敲出来的,特在此注明。
杭电1874弗洛伊德代码

# include <iostream>
# include <algorithm>
# include <cstring>
using namespace std;

const int maxn = 1e7;
int mapp[205][205], vis[205], len[205];

int main() {
	int n, m, a, b, x, s, t;
	while (cin >> n >> m) {
		memset(vis, 0, sizeof(vis));
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				mapp[i][j] = i == j ? 0 : maxn;
			}
			len[i] = maxn;
		}
		for (int i = 0; i < m; i++) {
			cin >> a >> b >> x;
			if (mapp[a][b] > x) {
				mapp[a][b] = mapp[b][a] = x;
			}
		}
		cin >> s >> t;
		for (int i = 0; i < n; i++) {
			len[i] = mapp[s][i];
		}
		vis[s] = 1;
		while (1) {
			int minn = maxn;
			int k = -1;
			for (int i = 0; i < n; i ++ ) {
				if (vis[i] == 0 && minn > len[i]) {
					minn = len[i];
					k = i;
				}
			}
			if (k == -1) {
				break;
			}
			vis[k] = 1;
			for (int i = 0; i < n; i++) {
				if (vis[i]==0 &&len[i] > len[k] + mapp[k][i]) {
					len[i] = len[k] + mapp[k][i];
				}
			}
		}
		if (len[t] == maxn) {
			cout << -1 << endl;
		}
		else {
			cout << len[t] << endl;
		}
	}
	return 0;
}

大佬的源码(有一点注释):

#include<stdio.h>
int mm[205][205];
int vis[205], len[205];
const int MAX = 0xfffffff;

int main() {
	int N, M;
	int a, b, x;
	int s, t;
	while (~scanf("%d%d", &N, &M)) {
		for (int i = 0; i < N; i++) {
			vis[i] = 0;   //所有城市标记为未访问
			len[i] = MAX;  //所有路径标记为无穷大 
		}
		for (int i = 0; i < N; i++) {//数组初始化 
			for (int j = 0; j < N; j++) {
				mm[i][j] = i == j ? 0 : MAX;
			}
		}
		for (int i = 0; i < M; i++) {//数据输入 
			scanf("%d%d%d", &a, &b, &x);
			if (mm[a][b] > x) {
				mm[a][b] = mm[b][a] = x;
			}
		}
		scanf("%d%d", &s, &t);

		//dijkstra算法
		for (int i = 0; i < N; i++) {//用于初始化标记s到i的距离
			len[i] = mm[s][i];
		}
		vis[s] = 1;//出发城市标记为已访问 
		while (1) {
			int min = MAX;
			int k = -1;
			for (int i = 0; i < N; i++) {//寻找下一个城市(路最短)

				if (vis[i] == 0 && len[i] < min) {
					min = len[i];
					k = i;
				}
			}
			if (k < 0) break;//所有城市都被标记完了
			vis[k] = 1;
			for (int i = 0; i < N; i++) {
				if (vis[i] == 0 && len[i] > len[k] + mm[k][i]) {
					len[i] = len[k] + mm[k][i];
				}
			}
		}
		printf("%d\n", len[t] == MAX ? -1 : len[t]);
	}
	return 0;
}

迪杰斯特拉最短路径算法是一种解决有权图中单源最短路径问题的算法。它采用贪心策略,以起始点为中心向外层层扩展,直到扩展到终点为止。该算法主要特点是将图中的节点集分为最短路径计算完成的节点集S和未计算完成的节点集T,每次将从T中挑选V0->Vt最小的节点Vt加入S,并更新V0经由Vt到T中剩余节点的更短距离,直到T中的节点全部加入S中。迪杰斯特拉算法只支持非负权图,它计算的是单源最短路径,即单个源点到剩余节点的最短路径,时间复杂度为O(n²)。 以下是迪杰斯特拉最短路径算法的具体步骤: 1. 初始化:将起始点s加入S集合,将与s直接相连的节点的距离加入dis数组,将其余节点的距离设为无穷大。 2. 重复执行以下步骤,直到T集合为空: a. 从dis数组中选择值最小的节点v,将其加入S集合。 b. 更新dis数组:对于T集合中的每个节点w,如果存在一条从v到w的边,则计算出v到w的距离,并将其与原有距离进行比较,如果更小则更新dis数组中w的值。 3. 得到起始点s到各个节点的最短路径。 以下是Python实现迪杰斯特拉最短路径算法的代码示例: ```python import sys def dijkstra(graph, start): # 初始化 dis = {node: sys.maxsize for node in graph} # 距离数组 dis[start] = 0 S = set() # 最短路径节点集合 T = set(graph.keys()) # 未计算最短路径节点集合 while T: # 选择距离起点最近的节点 v = min(T, key=lambda node: dis[node]) S.add(v) T.remove(v) # 更新距离数组 for w in graph[v]: if dis[w] > dis[v] + graph[v][w]: dis[w] = dis[v] + graph[v][w] return dis # 测试 graph = { 'A': {'B': 5, 'C': 1}, 'B': {'A': 5, 'C': 2, 'D': 1}, 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8}, 'D': {'B': 1, 'C': 4, 'E': 3, 'F': 6}, 'E': {'C': 8, 'D': 3}, 'F': {'D': 6} } start = 'A' print(dijkstra(graph, start)) # 输出:{'A': 0, 'B': 3, 'C': 1, 'D': 4, 'E': 7, 'F': 10} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值