【问题描述】
给定一个有向网,每个结点代表一个城市,边上的权值表示两个端点城市之间的距离,求给定的任意两个城市之间的最短路径。如果存在输出路径和路径距离,如果两个城市不可达则输出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
解题思路:
采用Dijstra算法,通过更新distance和path,生成最短路径。
完整代码:
#include <iostream>
#include <algorithm>
#define INT_MAX 9999
bool visited[100] = { 0 };
using namespace std;
typedef struct {
int vexs[100];
int arcs[100][100];
int vexnum, arcnum;
}Graph; //邻接矩阵表示法
void create_graph(Graph &G) {
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
G.vexs[i] = i;
}
int v1, v2, w;
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
if (i == j)
G.arcs[i][j] = 0;
else
G.arcs[i][j] = INT_MAX;
}
}
for (int i = 0; i < G.arcnum; i++) {
cin >> v1 >> v2 >> w;
G.arcs[v1-1][v2-1] = w; //注意审题,有向网络
}
}
void dijkstra(Graph &G, int v0,int d[100],int p[100]) {
for (int i = 0; i < G.vexnum; i++) {
visited[i] = 0;
d[i] = G.arcs[v0][i]; //distance距离集合初始化
p[i] = v0; //路径集合初始都为v0
}
visited[v0] = 1;
int k = 0;
for (int v = 0; v < G.vexnum; v++) {
int min = INT_MAX;
for (int w = 0; w < G.vexnum; w++) { //寻找当前最短路径
if (!visited[w]) {
if (d[w] < min) {
min = d[w];
k = w;
}
}
}
visited[k] = 1; // 访问此节点
for (int w = 0; w < G.vexnum; w++) { //更新d w数值
if (!visited[w] && (min + G.arcs[k][w]) < d[w]) {
d[w] = G.arcs[k][w] + min;
p[w] = k;
}
}
}
}
int main() {
Graph G;
create_graph(G);
int v0, vx;
cin >> v0 >> vx;
int d[100], p[100];
dijkstra(G, v0-1, d, p);
int path[100];
int count = 0;
int t = vx-1;
if (d[vx - 1] < INT_MAX) {
while (t != v0 - 1) {
path[count++] = p[t] + 1;
t = p[t];
}
while (count != 0) {
cout << path[--count] << " ";
} //倒序输出
cout << vx;
cout << endl;
cout << d[vx - 1] << endl;
}
else
cout << "0";
system("pause");
return 0;
}