#include <iostream> using namespace std; const int N = 5; const int E = 9; const int MAX = 0xffff; int ** g; /* * 函数返回Dn-1,其中Dk(i,j)表示顶点i到顶点j的“中间顶点都属于0,1,2,...,k”的最短路径p。 * 于是存在这样的子结构: * Dk(i,j) = * min{ Dk-1(i,j), Dk-1(i,k)+Dk-1(k,j)} k>=0 * g[i][j] k<0 * 对于k>=1的情况,如果Dk-1(i,j)<Dk-1(i,k)+Dk-1(k,j),说明从顶点i到顶点j的最短路径p中所有中间顶点都属于0,1,2,...,k-1,k不是路径p的中间节点。否则,如果k是路径p的中间节点,于是路径p分为i->k的p1和k->j的p2,而p1和p2具有相同的性质:p1和p2分别时i到k和k到j的最短路径,并且p1和p2的中间节点都属于0,1,2,...,k-1。于是便有了公式Dk-1(i,k)+Dk-1(k,j) * */ int** floyd_warshall(int ** g) { int i = 0,j=0; int ** d = new int*[N]; int **pre = new int*[N]; //初始化D-1 = G; //pre[i][j]表示从顶点i到顶点j的一条最短路径上顶点j的前驱 for(i=0;i<N;i++) { d[i] = new int [N]; pre[i] = new int[N]; for(j=0;j<N;j++) { d[i][j] =g[i][j]; if(i==j || g[i][j] == MAX)//初始化pre[i][j] pre[i][j] = -1; else pre[i][j] = i; } } for(i=0;i<N;i++) { for(j=0;j<N;j++) cout << pre[i][j] << " " ; cout << endl; } cout << endl; int k = 0; /* * 在此处迭代时,d1代表dk-1,d2代表dk */ int ** d1,**d2; int **p1,**p2; d1=d; p1 = pre; for(k=0;k<N;k++) { d2 = new int *[N]; p2 = new int*[N]; for(i=0;i<N;i++) { d2[i] = new int[N]; p2[i] = new int[N]; } for(i=0;i<N;i++) for(j=0;j<N;j++) { int tmp1 = d1[i][j]; int tmp2 = d1[i][k] + d1[k][j]; if(tmp1<=tmp2)//注意这里的<= { d2[i][j] = tmp1; p2[i][j] = p1[i][j]; } else { d2[i][j] = tmp2; p2[i][j] = p1[k][j]; } } for(i=0;i<N;i++) { delete []d1[i]; delete []p1[i]; } delete []d1; delete []p1; d1 = d2; p1 = p2; for(i=0;i<N;i++) { for(j=0;j<N;j++) cout << p1[i][j] << " " ; cout << endl; } cout << endl; } for(i=0;i<N;i++) { for(j=0;j<N;j++) cout << p1[i][j] << " " ; cout << endl; } cout << endl; return d1; } int main() { int i = 0; int j = 0; g = new int *[N]; for(i=0;i<N;i++) { g[i]= new int[N]; } for(i=0;i<N;i++) for(j=0;j<N;j++) if(i==j) g[i][j] = 0; else g[i][j] = MAX; int c = 0; while(c<E) { cin >> i; cin >> j; cin >> g[i][j]; c++; } int **d; d = floyd_warshall(g); for(i=0;i<N;i++) { for(j=0;j<N;j++) cout << d[i][j] << " " ; cout << endl; } }