每日算法:Dijkstra的最短路径求解pre数组

日期:2023.10.15

第5天

输入:

6 8 0
0 1 1
0 3 4
0 4 4
1 3 2
2 5 1
3 2 2
3 4 3
4 5 3

期望输出的最短距离(没有涉及到最短路径):

 

0 1 5 3 4 6

/*
	求路径需要增加一个pre[]数组 
*/

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1010;
int d[N];
bool vis[N] = {0};
int pre[N] = {-1};
int G[N][N];
int n, m, s;//顶点数、边数、起点 

void Dijkstra(int s) {
	memset(d, 0x3f, sizeof(d));
	d[s] = 0;
	
	//每个节点的前驱为自身; 
	for(int i = 0; i < n; i++) {
		pre[i] = i;
	}

	
	for(int i = 0; i < n; i++) {	//一共让集合S加入n个点 
		
		//第一层循环找非集合S中距离起点最近的 
		int MIN = INF, u = -1;
		for(int j = 0; j < n; j++) {
			if(vis[j] == 0 && d[j] < MIN) {
				MIN = d[j];
				u = j;
			} 
		}
		if(u ==-1) return ;
		vis[u] = 1;
		
		//更新非S集合中,和点U相连的点,到起点距离
		for(int j = 0; j < n; j++) {
			if(vis[j] == 0 && G[u][j] != INF) {
				d[j] = min(d[j], d[u] + G[u][j]);
				//它的前一个结点更新一下;
				pre[j] = u; 
			}
		} 
	}
}

//使用dfs()可以正着输出路径:要求:给出一个顶点,输入起点到这个点的路径,我们只知道它的前一个结点,先深度遍历到根节点

void dfs(int s, int v) {	//s是起点, v是目标点 
	//终止条件:
	if(v == s) {
		printf("%d ", s);
		return ;
	}
	dfs(s, pre[v]);
	printf("%d ", v); 
} 

int main(void) {
	scanf("%d%d%d", &n, &m, &s);
	memset(G, 0x3f, sizeof(G));
	for(int i = 0; i < m; i++) {
		int id1, id2, w;
		scanf("%d%d%d", &id1, &id2, &w);
		G[id1][id2] = w; 
	}
	Dijkstra(s);
	
	for(int i = 0; i < n; i++) {
		printf("最短距离%d\n ", d[i]);
		
		//如果用一个循环的话,只能倒着输出 
		printf("路径为:"); 
		for(int j = i; j >= 0; j = pre[j]) {
			printf("%d-->", j); 
			if(j == 0) break;
		} 
		printf("\n");
	}
	
	for(int i = 0; i < n; i++) {
		dfs(s, i);
		printf("\n");
	}
	return 0;
}

其他:这两天给ubuntu装n卡驱动,心态优点小崩。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前路漫漫亦灿灿上岸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值