利用邻接表构建无向图实现多源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 }
运行效果如下:

浙公网安备 33010602011771号