利用邻接表构建无向图实现多源spfa算法

前几天接了个任务,内容大概是在一张无向图中实现多源spfa算法。额,网上关于邻接表构图有很多现成的代码,spfa算法的教学更是数不胜数,但是笔者发现有关多起点的无向图构建与spfa算法结合的文章很少(很难找到现成的代码)。于是啊,笔者写了一套无向图多源spfa代码以供大家参考学习。

  1 #include <iostream>
  2 #include<queue>
  3 using namespace std;
  4 
  5 #define MVNum 100                            //最大顶点数
  6 
  7 int dis[1000],point[MVNum];                  //dis数组储存距离,而point数组记录点是否在队列中
  8 typedef char PointType;                        //顶点的数据类型
  9 typedef int OtherInfo;                        //和边相关的信息
 10 
 11 //图的邻接表存储表示
 12 typedef struct ArcNode {                        //边结点
 13     int adjvex;                                  //该边所指向的顶点的
 14     struct ArcNode* nextarc;                      //指向下一条边的指针
 15     OtherInfo value;                              //和边的权值
 16 }ArcNode;
 17 
 18 typedef struct VNode {
 19     PointType name;                                //顶点名字
 20     ArcNode* firstarc;                            //指向第一条依附该顶点的边的指针
 21 }VNode, AdjList[MVNum];                           //AdjList表示邻接表类型
 22 
 23 typedef struct {
 24     AdjList vertices;                             //邻接表
 25     int total_point, total_arc;                 //图的当前顶点数和边数
 26 }ALGraph;
 27 
 28 
 29 int LocateVex(ALGraph G, PointType v) {
 30     //确定点v在图中的位置,将数据类型转化
 31     for (int i = 0; i < G.total_point; ++i)
 32         if (G.vertices[i].name == v)
 33             return i;
 34     return -1;
 35 }//LocateVex
 36 
 37 int CreateUDG(ALGraph& G) {
 38     //采用邻接表表示法,创建无向图G
 39     int i, k;
 40 
 41     cout << "输入点的名称,如 A " << endl;
 42     for (i = 0; i < G.total_point; ++i) {              //输入各点,构造表头结点表
 43         cout << "请输入第" << (i + 1) << "个点的名称:";
 44         cin >> G.vertices[i].name;               //输入顶点值
 45         G.vertices[i].firstarc = NULL;            //初始化表头结点的指针域为NULL
 46     }//for
 47     cout << endl;
 48 
 49     cout << "请输入一条边依附的顶点,如 a b" << endl;
 50     for (k = 0; k < G.total_arc; ++k) {                //输入各边,构造邻接表
 51         PointType v1, v2;
 52         int i, j;
 53         cout << "请输入第" << (k + 1) << "条边依附的顶点:";
 54         cin >> v1 >> v2;                         //输入一条边依附的两个顶点
 55         i = LocateVex(G, v1);  j = LocateVex(G, v2);
 56         //确定v1和v2在G中位置,即顶点在G.vertices中的序号
 57 
 58         ArcNode* p1 = new ArcNode;                   //生成一个新的边结点*p1
 59         cout << "请输入第" << (k + 1) << "条边的权值:";
 60         cin >> p1->value;
 61         p1->adjvex = j;                               //邻接点序号为j
 62         p1->nextarc = G.vertices[i].firstarc;  G.vertices[i].firstarc = p1;
 63         //将新结点*p1插入顶点vi的边表头部
 64 
 65         ArcNode* p2 = new ArcNode;                //生成另一个对称的新的边结点*p2
 66         p2->adjvex = i;                             //邻接点序号为i
 67         p2->value = p1->value;
 68         p2->nextarc = G.vertices[j].firstarc;  G.vertices[j].firstarc = p2;
 69         //将新结点*p2插入顶点vj的边表头部
 70     }
 71     return 1;
 72 }//CreateUDG
 73 
 74 void spfa(ALGraph G)
 75 {
 76     queue<int> q;
 77     int j;
 78     char from_temp, to_temp;
 79     for (int i = 0; i <= G.total_point; i++)
 80     {
 81         dis[i] = 123456789;
 82         point[i] = 0;                            //0就是不在队列中
 83     }                                            //初始化
 84     cout << "输入起点和终点(如:A B),中间以空格隔开";
 85     cin >> from_temp >> to_temp;
 86     int from = LocateVex(G, from_temp);
 87     int to = LocateVex(G, to_temp);             //将结点从char转化为int,方便操作
 88     
 89     q.push(from); dis[from] = 0; point[from] = 1;//队首入队
 90     while (!q.empty())
 91     {
 92         int u = q.front();                      //取出队首
 93         q.pop(); point[u] = 0;
 94         ArcNode* p = G.vertices[u].firstarc;
 95 
 96         while (p)
 97             {
 98                  j = p->adjvex;
 99                 if (dis[j] > dis[u] + p->value)
100                 {
101                     dis[j] = dis[u] + p->value;
102                     if (point[j] == 0)
103                     {
104                         point[j] = 1;
105                         q.push(j);
106                     }
107                 }
108                 p = p->nextarc;
109             }
110     }
111     cout << dis[to];
112 
113 }
114 
115 int main() {
116     cout << "************采用邻接表表示法创建无向图**************" << endl << endl;
117     cout << "请输入总顶点数,总边数中间以空格隔开:";
118     ALGraph G;
119     cin >> G.total_point >> G.total_arc;                //输入总顶点数,总边数
120     cout << endl;
121     CreateUDG(G);
122     int i;
123     cout << endl;
124     cout << "*****邻接表表示法创建的无向图*****" << endl;
125 
126     for (i = 0; i < G.total_point; ++i) {
127         VNode temp = G.vertices[i];
128         ArcNode* p = temp.firstarc;
129         if (p == NULL) {
130             cout << G.vertices[i].name;
131             cout << endl;
132         }
133         else {
134             cout << temp.name;
135             while (p) {
136                 cout << "-> ";
137                 cout << G.vertices[p->adjvex].name;
138                 p = p->nextarc;
139             }
140         }
141         cout << endl;
142     }                                                   //打印邻接表
143     spfa(G);
144     return 0;
145 }

运行效果如下:

 

posted @ 2022-02-23 15:36  SandaiYoung  阅读(65)  评论(0)    收藏  举报