(visual studio 2019可运行)
输入及输出要求见《数据结构C语言(第二版)》严蔚敏版
【本文仅用于啥都看不懂还想交作业选手】
加了一点输入异常的反馈
基于基于Dijsktra算法的最短路径求解 - 简书改动
(这是一个我终于明白并不需要一次性统一输出的故事)
#includeusing namespace std; #define MAXSIZE 100 #define OK 1 typedef int Status; //用两个数组分别存储顶点表和邻接矩阵 #define MaxInt 32767 //表示极大值,即∞ #define MVNum 100 //最大顶点数 typedef char VerTexType; //假设顶点的数据类型为字符型 typedef int ArcType; //假设边的权值类型为整型 typedef struct { VerTexType vexs[MVNum]; //顶点表 ArcType arcs[MVNum][MVNum]; //邻接矩阵 int vexnum;//图的总点数 int arcnum;//图的总边数 }AMGraph; int LocateVex(AMGraph G, VerTexType u) {//存在则返回u在顶点表中的下标;否则返回-1 int i; for (i = 0; i < G.vexnum; ++i) if (u == G.vexs[i]) return i; return -1; } VerTexType OrigialVex(AMGraph G, int u) {//存在则返回u在顶点表中的下标;否则返回-1 return G.vexs[u]; } Status CreateUDN(AMGraph& G) { //采用邻接矩阵表示法,创建无向网G cin >> G.vexnum; //输入总顶点数 cin >> G.arcnum; //输入总边数 int i, j, k, w; VerTexType v1, v2; for (i = 0; i < G.vexnum; ++i) cin >> G.vexs[i]; //依次输入点的信息 for (i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值 for (j = 0; j < G.vexnum; ++j) G.arcs[i][j] = MaxInt; for (k = 0; k < G.arcnum; ++k) { //构造邻接矩阵 cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值 i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置 G.arcs[i][j] = w; //边 的权值置为w G.arcs[j][i] = G.arcs[i][j]; //置 的对称边 的权值为w } return OK; } Status CreateDN(AMGraph& G, int dian, int bian) { //创建有向网G的邻接矩阵 G.vexnum = dian; G.arcnum = bian; int i, j, k, w; VerTexType v1, v2; for (i = 0; i < G.vexnum; ++i) cin >> G.vexs[i]; //依次输入点的信息 for (i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值 for (j = 0; j < G.vexnum; ++j) G.arcs[i][j] = MaxInt; for (k = 0; k < G.arcnum; ++k) { //构造邻接矩阵 cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值 i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置 G.arcs[i][j] = w; //边 的权值置为w } return OK; } int D[MVNum], Path[MVNum],S[MVNum]; void ShortestPath_DIJ(AMGraph G, VerTexType V) { //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径 int i, n, v, min, w; n = G.vexnum; //n为G中顶点的个数 int v0 = LocateVex(G, V); for (v = 0; v < n; ++v) { //n个顶点依次初始化 S[v] = false; //S初始为空集 D[v] = G.arcs[v0][v]; //将v0到各个终点的最短路径长度初始化 if (D[v] < MaxInt) Path[v] = v0; //v0和v之间有弧,将v的前驱置为v0 else Path[v] = -1; //如果v0和v之间无弧,则将v的前驱置为-1 } S[v0] = true; //将v0加入S D[v0] = 0; //源点到源点的距离为0 D[-1] = -1; //出现异常顶点 for (i = 1; i < n; ++i){ //对其余n−1个顶点,依次进行计算 min = MaxInt; for (w = 0; w < n; ++w) if (!S[w] && D[w] < min) { v = w; min = D[w]; } //选择一条当前的最短路径,终点为v S[v] = true; //将v加入S for (w = 0; w < n; ++w) //更新从v0出发到集合V−S上所有顶点的最短路径长度 if (!S[w] && (D[v] + G.arcs[v][w] < D[w])) { D[w] = D[v] + G.arcs[v][w]; //更新D[w] Path[w] = v; //更改w的前驱为v } } } void find(AMGraph G, int v,char A) { int n = G.vexnum; if (Path[v] == -1||v==-1) return; else { find(G, Path[v],A); cout << OrigialVex(G, Path[v]) << " "; } } int main() { char A, B; int a, b; while (cin >> a >> b && a && b) { AMGraph G; CreateDN(G, a, b); cin >> A; ShortestPath_DIJ(G, A); cin >> B; int n = LocateVex(G, B); cout << D[n] << endl; find(G, n,A); if (D[n] == -1)//异常查找 cout << "wrong point!" << endl; else cout << B << endl; } return 0; }



