多条单源最短路径 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