算法上机实验----单源+点对最短距离 发表于 2017-12-16 | 分类于 算法 Berman-Ford算法以及动态规划法求解 图的数据结构定义 单源最短路径的Berman-Ford算法是基于边的图算法,所以我使用二维的数组存储图的边数据。 点对最短路径是基于个点的,所以用邻接矩阵来存储图。 1234567891011121314151617181920212223242526272829303132#include <stdio.h>#define INF 100000// int Graph1[5][5] = {// {INF, 6, INF, 7, INF},// {INF, INF, 5, 8, -4},// {INF, -2, INF, INF, INF},// {INF, INF, -3, INF, 9},// { 2, INF, 7, INF, INF}// };char Graph1_V_name[5] = {'s', 't', 'x', 'y', 'z'};int Graph1[10][3] = { {0, 1, 6}, {0, 3, 7}, {1, 2, 5}, {1, 3, 8}, {1, 4, -4}, {2, 1, -2}, {3, 2, -3}, {3, 4, 9}, {4, 0, 2}, {4, 2, 7}};int Graph2[5][5] = {// 1 2 3 4 5 { 0, 3, 8, INF, -4}, //1 {INF, 0, INF, 1, 7}, //2 {INF, 4, 0, INF, INF}, //3 { 2, INF, -5, 0, INF}, //4 {INF, INF, INF, 6, 0}, //5}; 单源最短路径的实现 12345678910111213141516171819202122232425262728293031323334353637void solve_single_sourse(int v_n, int e_n) { int P[v_n]; int D[v_n]; for (int i = 0; i < v_n; i++) { P[i] = -1; D[i] = INF; } D[0] = 0; // 求解算法 for (int k = 0; k < v_n-1; k++) { for (int i = 0; i < e_n; i++) { int u = Graph1[i][0]; int v = Graph1[i][1]; int w = Graph1[i][2]; if (D[v] > D[u] + w) { D[v] = D[u] + w; P[v] = u; } } } // 回溯法求解路径 char path[v_n]; for (int k = 1; k < v_n; k++) { int l = 0; int v = k; printf("l:%2d ", D[k]); while(P[v] != -1) { path[l++] = Graph1_V_name[v]; v = P[v]; } printf("s"); for (l--; l >=0; l--) { printf("->%c", path[l]); } printf("\n"); }} 运行结果 1234l: 2 s->y->x->tl: 4 s->y->xl: 7 s->yl:-2 s->y->x->t->z 各点对最短路径 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647void solve_pair_distance(int n) { int L[n][n]; int P[n][n]; // 算法主体 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { L[i][j] = Graph2[i][j]; P[i][j] = -1; } } for (int m = 1; m < n-1; m++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { if (L[i][j] > L[i][k] + Graph2[k][j]) { L[i][j] = L[i][k] + Graph2[k][j]; P[i][j] = k; // 记录从i到j这条路径上的父节点 } } } } } // 输出各点对之间的最短距离 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { printf("%3d ", L[i][j]); } printf("\n"); } // 根据P找出路径 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) continue; printf("%d->", i+1); int buff[n], l = 0; int v = j; while(P[i][v] != -1) { buff[l++] = P[i][v]; v = P[i][v]; } for(l--; l>=0; l--) { printf("%d->", buff[l]+1); } printf("%d\n", j+1); } }} 运行结果 12345678910111213141516171819202122232425 0 1 -3 2 -4 3 0 -4 1 -1 7 4 0 5 3 2 -1 -5 0 -2 8 5 1 6 0 1->5->4->3->21->5->4->31->5->41->52->4->12->4->32->42->4->1->53->2->4->13->23->2->43->2->4->1->54->14->3->24->34->1->55->4->15->4->3->25->4->35->4 主函数 12345int main() { // solve_single_sourse(5, 10); solve_pair_distance(5); return 0;}