一.问题描述
给定带权有向图G=(V,E),对任意顶点 V (ij),求顶点到顶点的最短路径。
转化为:
多源点最短路径求解问题
解决方案一:
每次以一个顶点为源点调用Dijksra算法。时间复杂度为O()
解决方法二:
Floyd算法
二.弗洛伊德算法的基本思想
对于从到的弧,进行n次试探:首先考虑路径是否存在,如果存在,则比较和的路径长度,取较短者为从到的中间顶点的序号不大于0的最短路径。在路径上再增加一个顶点,以此类推,在经过n次比较后,最后求得从顶点到得最短路径。
三.弗洛伊德算法的实现
cpp
#include <iostream>
#include <cstring>
#include <stack>
using namespace std;
const int MAX_VERTEX=10;
//带权(邻接矩阵)有向图
class MGraph{
private:
int arc[MAX_VERTEX][MAX_VERTEX];//邻接矩阵
int vertex[MAX_VERTEX];//存储每个结点的信息
int vertexNum,arcNum;//实际顶点个数,边的条数
public:
MGraph(int n,int e);
void Dijkstra(int start);
int findMinDist(int dist[],int s[]);
void display();
void displayPath(int dist[],int path[],int start,int min);
void Floyd();
char* string_concatenation(char *s1,char *s2);
};
int main(int argc, const char * argv[]) {
MGraph G(5, 7);
G.display();
G.Floyd();
//G.Dijkstra(0);
//ALGraph G(7, 10);
//G.topology();
return 0;
}
MGraph::MGraph(int n,int e){
int p,q,w;
vertexNum=n;
arcNum=e;
for(int i=0;i<n;i++){//初始化邻接矩阵
for(int j=0;j<n;j++){
arc[i][j]=-1;//-1表示不可到达
}
}
for(int i=0;i<n;i++){
vertex[i]=i;
arc[i][i]=0;
}
for(int i=0;i<e;i++){
cin>>p>>q>>w;
arc[p][q]=w;
}
}
void MGraph::Floyd(){
int dist[vertexNum][vertexNum],i,j,k;
char* path[vertexNum][vertexNum];
for(i=0;i<vertexNum;i++){//初始化
for(j=0;j<vertexNum;j++){//path,dist数组初始化
dist[i][j]=arc[i][j];
if(arc[i][j]!=-1){
path[i][j]=new char[3];
path[i][j][0]=i+'a';
path[i][j][1]=j+'a';
path[i][j][2]='\0';
}
else{
path[i][j]=new char[1];
path[i][j][0]='\0';
}
}
}
for(k=0;k<vertexNum;k++){
for(i=0;i<vertexNum;i++){
for(j=0;j<vertexNum;j++){
if(dist[i][k]!=-1&&dist[k][j]!=-1){
if(dist[i][j]>dist[i][k]+dist[k][j]||dist[i][j]==-1){
dist[i][j]=dist[i][k]+dist[k][j];
delete [] path[i][j];
path[i][j]=string_concatenation(path[i][k], path[k][j]);
}
}
}
}
}
for(i=0;i<vertexNum;i++){
for(j=0;j<vertexNum;j++){
if(j!=i){
cout<<path[i][j]<<endl;
}
delete [] path[i][j];
}
}
}
char* MGraph::string_concatenation(char *s1,char *s2){
int len1=(int)strlen(s1);
int len2=(int)strlen(s2);
int k=1,i;
const int n=len1+len2;
char *path=new char[n];
for(i=0;i<len1;i++){
path[i]=s1[i];
}
for(;i<len1+len2-1;i++){
path[i]=s2[k++];
}
path[i]='\0';
return path;
}