對於一個各邊權值均大於零的有向圖,對每一對頂點,求出vi與vj之間的最短路徑和最短路徑長度。
以下代碼包含有向圖的建立,Floyd算法的實現以及輸出最短路徑和最短路徑長度。
代碼說明幾點:
1、A[][]數組初始化爲各頂點間的原本距離,最後存儲各頂點間的最短距離。
2、path[][]數組保存最短路徑,與當前迭代的次數有關。初始化都爲-1,表示沒有中間頂點。在求A[i][j]過程中,path[i][j]存放從頂點vi到頂點vj的中間頂點編號不大於k的最短路徑上前一個結點的編號。在算法結束時,由二維數組path的值回溯,可以得到從頂點vi到頂點vj的最短路徑。
初始化A[][]數組爲如下,即有向圖的鄰接矩陣。
完整的實現代碼如下:
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
#define MaxVertexNum 100
#define INF 32767
typedef struct
{
char vertex[MaxVertexNum];
int edges[MaxVertexNum][MaxVertexNum];
int n,e;
}MGraph;
void CreateMGraph(MGraph &G)
{
int i,j,k,p;
cout<<"請輸入頂點數和邊數:";
cin>>G.n>>G.e;
cout<<"請輸入頂點元素:";
for (i=0;i<G.n;i++)
{
cin>>G.vertex[i];
}
for (i=0;i<G.n;i++)
{
for (j=0;j<G.n;j++)
{
G.edges[i][j]=INF;
if (i==j)
{
G.edges[i][j]=0;
}
}
}
for (k=0;k<G.e;k++)
{
cout<<"請輸入第"<<k+1<<"條弧頭弧尾序號和相應的權值:";
cin>>i>>j>>p;
G.edges[i][j]=p;
}
}
void Dispath(int A[][MaxVertexNum],int path[][MaxVertexNum],int n);
void Floyd(MGraph G)
{
int A[MaxVertexNum][MaxVertexNum],path[MaxVertexNum][MaxVertexNum];
int i,j,k;
for (i=0;i<G.n;i++)
{
for (j=0;j<G.n;j++)
{
A[i][j]=G.edges[i][j];
path[i][j]=-1;
}
}
for (k=0;k<G.n;k++)
{
for (i=0;i<G.n;i++)
{
for (j=0;j<G.n;j++)
{
if (A[i][j]>A[i][k]+A[k][j])
{
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}
}
}
Dispath(A,path,G.n);
}
void Ppath(int path[][MaxVertexNum],int i,int j)
{
int k;
k=path[i][j];
if (k==-1)
{
return;
}
Ppath(path,i,k);
printf("%d",k);
Ppath(path,k,j);
}
void Dispath(int A[][MaxVertexNum],int path[][MaxVertexNum],int n)
{
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
if (A[i][j]==INF)
{
if (i!=j)
{
printf("從%d到%d沒有路徑/n",i,j);
}
}
else
{
printf(" 從%d到%d=>路徑長度:%d路徑:",i,j,A[i][j]);
printf("%d,",i);
Ppath(path,i,j);
printf("%d/n",j);
}
}
}
}
int main()
{
MGraph G;
CreateMGraph(G);
Floyd(G);
return 0;
}
之前在我新浪博客的文章~