多条单源最短路径

多条单源最短路径 C++版

1.题意

给出一个图,找出到某个点的最短路径,并输出路径。如果最短路径有多条,则全部输出。

2.分析
  • step1:dijkstra 算法
  • step2:dfs深搜
3.代码
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 505
#define INF 0x3fffff

using namespace std;
int Cmax,N,Sp,M;	
vector<int> path[maxn];//路径信息 
int d[maxn];
int curNum[maxn];//表示当前车站的车数 
int G[maxn][maxn];//用于存储图的边信息 
int isVisit[maxn];//表示是否访问过 

void init(){
	fill(G[0],G[0]+(maxn*maxn),INF);//初始值为INF
	fill(d,d+maxn,INF);//初始值为INF
	fill(isVisit,isVisit+maxn,0);//0=未访问 
} 

void dijkstra(int s){//求单源最短路径 		 
	int min = INF;//当前这一轮里最短的距离  初始化为INF 
	int u;//最短距离所对应的节点编号 
	int i ;
	for(i = 0;i <= N;i++){//找最短的距离 
		if(d[i] < min && isVisit[i] == 0) { 
			min = d[i];//更新
			u = i; 
		}	 
	} 
	isVisit[u] = 1; //标记已访问 
	//将u节点 作为中间节点更新 d[maxn] 
	for(i = 0;i <= N;i++){
		if(d[u] + G[u][i] < d[i] && isVisit[i] == 0){//说明通过u作为中间节点距离更短 
			d[i] =  d[u] + G[u][i] ;//更新
			path[i].clear();//清除之前的信息
			path[i].push_back(u);//添加到u 
		}
		else if(d[u] + G[u][i] == d[i] && isVisit[i] == 0){
			path[i].push_back(u);//添加一个新的节点 
		}
	}
}

vector<int> ans;//用于存储结果路径 

//找出所有的路径,然后判断最优的一条 
void dfs(int node){
	int i;
	for(i = 0;i < path[node].size();i++){
		ans.push_back(path[node][i]); 		
		if(path[node][i] == 0){
			for(int j = 0;j< ans.size();j++){
				cout << ans[j] <<" ";
			}
			cout <<"\n";
		}		
		dfs(path[node][i]);//往下一层 
		ans.pop_back();//删除上个元素		
	}
}

int main(){
	cin >> N >> M;
	init(); 
	int i,j;
	int ver1,ver2,edge;//顶点信息   边信息
	for(i = 0;i< M;i++){
		cin >> ver1 >> ver2>> edge; 
		G[ver1][ver2] = edge;//表示有边 
		G[ver2][ver1] = edge;		
	}
	//需要调用dijkstra算法N次 
	d[0]=0;//到自己的距离为0
	for(i = 0;i<= N;i++)	dijkstra(0);	
	for(i = 0;i<= N;i++){
		cout <<"i = "<<i<<", d[i] = "<< d[i] <<"\n";
	}
	
	//输出到节点3的路径条数 
	int des = 4;		
	ans.push_back(des);
	dfs(des); 
}
4.测试用例```
3 5
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1

4 7
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1
2 4 4
3 4 1

在这里插入图片描述

5.执行结果

在这里插入图片描述

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

说文科技

看书人不妨赏个酒钱?

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

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

打赏作者

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

抵扣说明:

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

余额充值