当前位置:   article > 正文

C++ || 数据结构 -- 邻接矩阵&最短路径Dijsktra算法_c数据结构一张地图包括 n 个城市,假设城市间有 m 条路径(有向图),每条路径的长 度

c数据结构一张地图包括 n 个城市,假设城市间有 m 条路径(有向图),每条路径的长 度

问题描述:

 

一张地图包括n个城市,假设城市间有m条路径(有向图),每条路径的长度已知。给定地图的一个起点城市和终点城市,利用 Dijsktra算法求出起点到终点之间的最短路径。

输入要求:

多组数据,每组数据有m+3行。第一行为两个整数n和m,分别代表城市个数n和路径条数m。第二行有n个字符,代表每个城市的名字。第三行到第m+2行每行有两个字符a和 b和一个整数d,代表从城市α到城市b有一条距离为d的路。最后一行为两个字符,代表待求最短路径的城市起点和终点。当n和 m都等于0时,输入结束。

输出要求:

每组数据输出2行。第1行为一个整数,为从起点到终点之间最短路的长度。第2行为一串字符串,代表该路径。每两个字符之间用空格隔开。

输入样例:

3 3

A B C

A B 1

B C 1

C A 3

A C

6 8

A B C D E F

A F 100

A E 30

A C 10

B C 5

C D 50

D E 20

E F 60

D F 10

A F

0 0

输出样例:

2

A B C

70

A E D F

  1. #include <iostream>
  2. using namespace std;
  3. #define MaxInt 32567 //表示极大值,即正无穷
  4. #define MVNum 100 //最大定点数
  5. #define OK 1
  6. typedef char VerTexType;//假设顶点的数据类型为字符型 vertex顶点
  7. typedef int ArcType;//假设边的权值类型为整型
  8. typedef struct {
  9.     VerTexType vexs[MVNum];//顶点表
  10.     ArcType arcs[MVNum][MVNum];//邻接矩阵
  11.     int vexnum, arcnum;//图的当前点数和边数
  12. }AMGraph;
  13. VerTexType IndexVex(AMGraph G, int u) {//存在则返回u在顶点表中的下标,否则返回-1
  14.     return G.vexs[u];
  15. }
  16. int LocateVex(AMGraph G, VerTexType v) {
  17.     for (int i = 0; i < G.vexnum; i++) {
  18.         if (v == G.vexs[i])//输入的顶点v在G中找到
  19.             return i;
  20.     }
  21.     return -1;
  22. }
  23. int CreateUDN(AMGraph& G) {//采用邻接矩阵表示法,创建无向网G
  24.     char v1, v2;
  25.     int w;
  26.     cin >> G.vexnum >> G.arcnum;//输入总顶点数,总边数
  27.     for (int i = 0; i < G.vexnum; ++i)
  28.         cin >> G.vexs[i];
  29.     for (int i = 0; i < G.vexnum; ++i)//初始化邻接矩阵,边的最大权值设置为极大值MaxInt
  30.         for (int j = 0; j < G.vexnum; ++j)
  31.             G.arcs[i][j] = MaxInt;
  32.     int i, j;
  33.     for (int k = 0; k < G.arcnum; ++k) {//构造邻接矩阵
  34.         cin >> v1 >> v2 >> w;//输入一条边依附的顶点及权值
  35.         i = LocateVex(G, v1);
  36.         j = LocateVex(G, v2);//确定v1和v2在G中的位置,即顶点数组的下标
  37.         G.arcs[i][j] = w;//边<v1,v2>的权值置为w
  38.         G.arcs[j][i] = G.arcs[i][j];//置<v1,v2>的对称边<v2,v1>的权值为w
  39.     }
  40.     return OK;
  41. }
  42. int CreateDN(AMGraph& G,int vex,int edge) {//采用邻接矩阵表示法,创建有向网G
  43.     char v1, v2;
  44.     int w;
  45.    
  46.     //cin >> G.vexnum >> G.arcnum;//输入总顶点数,总边数
  47.     G.vexnum = vex;//总顶点数
  48.     G.arcnum = edge;//总边数
  49.     for (int i = 0; i < G.vexnum; ++i)
  50.         cin >> G.vexs[i];
  51.     for (int i = 0; i < G.vexnum; ++i)//初始化邻接矩阵,边的最大权值设置为极大值MaxInt
  52.         for (int j = 0; j < G.vexnum; ++j)
  53.             G.arcs[i][j] = MaxInt;
  54.            
  55.     int i, j;
  56.     for (int k = 0; k < G.arcnum; ++k) {//构造邻接矩阵
  57.         cin >> v1 >> v2 >> w;//输入一条边依附的顶点及权值
  58.         i = LocateVex(G, v1);
  59.         j = LocateVex(G, v2);//确定v1和v2在G中的位置,即顶点数组的下标
  60.         G.arcs[i][j] = w;//边<v1,v2>的权值置为w
  61.         //G.arcs[j][i] = G.arcs[i][j];//置<v1,v2>的对称边<v2,v1>的权值为w
  62.     }//for
  63.     return OK;
  64. }
  65. int D[MVNum], Path[MVNum];
  66. void ShortestPath_DIJ(AMGraph G, VerTexType V) {//用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径
  67.     int n, w, v, min;
  68.     int S[MVNum];
  69.     n = G.vexnum;//n是顶点的个数
  70.     int v0 = LocateVex(G, V);
  71.     for (v = 0; v < n; v++) {
  72.         S[v] = false;//S初始为空集
  73.         D[v] = G.arcs[v0][v];//将v0到各个终点的最短路径长度初始化为弧上的权值
  74.         if (D[v] < MaxInt) {
  75.             Path[v] = v0;//如果v0和v之间有弧,则将v前驱置为v0
  76.         }
  77.         else {
  78.             Path[v] = -1;//如果v0和v之间无弧,则将v前驱置为-1
  79.         }
  80.     }//for
  81.     S[v0] = true;//将v0加入S
  82.     D[v0] = 0;//源点到源点的距离为0
  83.    
  84.     /*————————初始化结束,开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集————————*/
  85.    
  86.     for (int i = 1; i < n; i++) {//对其余n-1个顶点,依次进行计算
  87.         min = MaxInt;
  88.         for (w = 0; w < n; ++w) {
  89.             if (!S[w] && D[w] < min) {
  90.                 v = w; min = D[w];//选择一条当前的最短路径,终点为v
  91.             }
  92.         }
  93.         S[v] = true;//将v加入S
  94.         for (w = 0; w < n; w++) {//更新从v0出发到集合V-S上所有顶点的最短路径长度
  95.             if (!S[w] && (D[v] + G.arcs[v][w] < D[w])) {
  96.                 D[w] = D[v] + G.arcs[v][w];//更新D[w]
  97.                 Path[w] = v;//更改w的前驱为v
  98.             }//if
  99.         }
  100.     }//for
  101. }
  102. void Search(AMGraph G, int v) {
  103.     if (Path[v] == -1)
  104.         return;
  105.     else {
  106.         Search(G, Path[v]);
  107.         cout << IndexVex(G, Path[v]) << " ";
  108.     }
  109. }
  110. int main() {
  111.     char city1, city2;//城市名字,起点、终点
  112.     char str[]={',','.','/','*',';',':','+','-','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  113.     int a, b;//n个城市,m条路径
  114.     cout << "请输入城市个数以及路径条数(需用空格分隔)--注意:输入 0 0结束输入:\n";
  115.     while (cin >> a >> b && a && b) {
  116.         cout << "请输入城市之间路径距离(需用空格分隔):\n";
  117.         AMGraph G;
  118.         CreateDN(G, a, b);
  119.         cin >> city1;
  120.         ShortestPath_DIJ(G, city1);
  121.         cin >> city2;
  122.         int n = LocateVex(G, city2);
  123.         cout << "最短路长为:" << D[n] << endl;
  124.         cout << "最短路径为:";
  125.         Search(G, n);
  126.         cout << city2 << endl;
  127.     }
  128.     return 0;
  129. }

验证:

输入:

3 3

A B C

A B 1

B C 1

C A 3

A C

6 8

A B C D E F

A F 100

A E 30

A C 10

B C 5

C D 50

D E 20

E F 60

D F 10

A F

0 0

输出结果如下图所示:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/711056
推荐阅读
相关标签
  

闽ICP备14008679号