【问题描述】给定一个有向网,每个结点代表一个城市,边上的权值表示两个端点城市之间的距离,求给定的任意两个城市之间的最短路径。如果存在输出路径和路径距离,如果两个城市不可达则输出0.
【输入形式】
7 8 //结点数(结点编号从1开始连续编码),边的数量
1 2 4 //每个活动的起点和终点,活动完成所需时间
1 3 3
2 4 5
3 4 3
4 5 1
4 6 6
5 7 5
6 7 2
1 6 //起点和终点
【输出形式】
如果存在路径则输出最短路径和路径值:
1 3 4 6
12
如果不存在则输出:
0
本代码采用图的深度优先遍历求最短路径
代码如下
#include<iostream>
using namespace std;
int min = 99999, end, start, book[101] = { 0 }, n, e[101][101];//假设99999为正无穷
int arr[101] = { 0 };
//cur是当前城市所在的编号,dis是当前已经走过的路程
void dfs(int cur, int dis)
{
int j;
//如果当前走过的路程已经大于之前找到的最短路,则没有必要再往下尝试,立即停止
if (dis > ::min)//::为当前程序作用域,因为min与vs全局变量冲突,所以需要指明作用域,也可通过修改变量名解决
{
return;
}
if (cur == ::end)//判断是否到达目标城市
{
if (dis < ::min)
{
::min = dis;
for (int i = 0; i <=n; i++)//记录最短路径
arr[i] = book[i];
}
return;
}
for (j = 1; j <= ::end; j++)//从1号到n号城市依次尝试
{
//判断当前城市cur到城市j是否有路,并判断j是否在已走过的路径中
if (e[cur][j] != 99999 && book[j] == 0)
{
book[j] = 1;//标记城市j已经在路径中
dfs(j, dis + e[cur][j]);
book[j] = 0;//之前一步探索完之后,取消对城市j的标记
}
}
return;
}
int main()
{
int i, j, m, a, b, c;
cin >> n >> m;
//初始化二维矩阵
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (i == j)
e[i][j] = 0;
else
e[i][j] = 99999;
//读入城市间的道路
for (i = 1; i <= m; i++)
{
cin >> a >> b >> c;
e[a][b] = c;
}
//从start号城市出发
cin >> start >> ::end;
arr[start] = 1;
book[start] = 1;//标记一号城市已经在路径中
dfs(start, 0);//1表示当前城市所在的编号,0表示当前已经走的路径
if (::min == 99999)
{
cout << 0;
return 0;
}
for (int i = 0; i < 101; i++)
{
if (arr[i] != 0)
cout << i << " ";
}
cout << endl;
cout << ::min;
return 0;
}