Dijkstra单源最短路径

文章介绍了如何使用Dijkstra算法解决单源最短路径问题,并详细解释了C++代码中如何在输出部分实现路径编号和NoPathto的输出。代码展示了如何在遍历过程中维护节点间的最短路径信息并按照特定顺序打印结果。
摘要由CSDN通过智能技术生成

Dijkstra单源最短路径

总提交数: 1725次通过数: 550次通过率: 31.88%

内存限制: 10485760(BYTE)时间限制: 1000(MS)输入限制: 1000(行)输出限制: 1000(行)

题目描述

一个有向图中有  个顶点和  条单向路径 , 请使用Dijkstra算法,求出某一个顶点到其他顶点的最短路径。

Input Format

第一行两个正整数  和 ,分别代表点的数量和路径的数量。   1< <20, 0<=  <50

之后  行每行有三个整数  分别表示 路径 的起点、终点序号和路径长度。顶点编号从1开始,0<i,j<=n,0<k<100

源点编号p ,0<p<=n

Output Format

Ⅰ.Dijkstra计算过程;

Ⅱ.输出给定点v到其他各点的路径,以及最短距离。

注意输出格式

橘色点代表空格。CRLF代表换行。

按照Dijkstra算法获取最短路径顺序进行输出,如果没有路径则输出“No Path to ”【顶点编号,升序排列,中间使用空格隔开】

样例输入输出

样例1

输入:

8 10
1 6 10
1 5 5
6 3 1
6 5 2
3 4 4
4 1 7
4 3 6
5 6 3
5 3 9
5 4 2
1

输出:

No.1 : 1 -> 5 , d = 5
No.2 : 1 -> 5 -> 4 , d = 7
No.3 : 1 -> 5 -> 6 , d = 8
No.4 : 1 -> 5 -> 6 -> 3 , d = 9
No.5 : No Path to 2 7 8

代码:

Dijkstra部分就略过,主要讲一下输出部分的No怎么实现。

很明显,如果要有输出的序号,将输出放入dijkstra内部,随着进程不断输出是一种不错解决方式,然后定义一个time变量每次输出时就加一,这样就能实现序号的输出,值得注意的是time++需要写在if()语句内,有输出时才有time++,最后判断no path to情况,值得注意的是,当没有这种情况存在时,不需要单独输出一个no path to

#include<iostream>
using namespace std;
int *parent;
void output(int start,int m) {
	if(parent[m] != start) {
		output(start, parent[m]);
	}
	cout << "-> " << m+1 << " ";
}
int main() {
	int n, m;
	cin >> n >> m;
	int** a = new int* [n];
	for (int i = 0; i < n; i++) {
		a[i] = new int[n];
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			a[i][j] = -1;
			if (i == j)a[i][j] = 0;
		}
	}
	for (int i = 0; i < m; i++) {
		int x, y;
		cin >> x >> y;
		cin >> a[x-1][y-1];
	}
	int* min = new int[n];
	int* visited = new int[n];
	min[0] = 0;
	for (int i = 0; i < n; i++) {
		min[i] = 1000;
		visited[i] = 0;
	}
	parent = new int[n];
	int c = 0;
	int cur;
	cin >> cur;
	cur = cur - 1;
	int start = cur;
	min[cur] = 0;
	int time = 1;
	int t = 1;
	for (int i = 0; i < n; i++) {
		parent[i] = start;
	}
	while (c < n-1) {
		for (int j = 0; j < n; j++) {
			if (a[cur][j] != -1&& a[cur][j]+min[cur] < min[j]) {
				min[j] = a[cur][j] +min[cur];
				parent[j] = cur;
			}
		}
		visited[cur] = 1;
		int t = 0;
		int m;
		c = 0;
		for (int i = 0; i < n; i++) {
			if (visited[i] == 1)c++;
			else {
				if (t == 0) {
					m = i;
					t++;
				}
				else if (min[m] > min[i]) {
					m = i;
				}
			}
		}
		if (min[m] != 1000) {
			cout << "No." << time << " : " << start + 1 << " ";
			output(start, m);
			cout << ", " << "d = " << min[m] << endl;
			time++;
		}
		cur = m;
	}
	int* nopath = new int[n];
	int end = -1;
	for (int i = 0; i < n; i++) {
		if (min[i] == 1000) {
			end++;
			nopath[end] = i;
		}
	}
	if (end >= 0) {
		cout << "No."<<time<<" : No Path to";
		for (int i = 0; i <= end; i++)
			cout  << " " << nopath[i]+1;
	}
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值