//Floyd最短路径算法思想:对每条链接尝试插入新节点后计算代价,然后和原代价进行比较,如果新代价较小,则更新代价矩阵
//Floyd算法使用3层for循环,内2层循环用于更新花费矩阵和路径记录矩阵,外循环进行插入尝试找新的最短路径
//两个辅助矩阵cost[ ][ ]和p[ ][ ]分别记录两顶点当前最短路径花费和经过的中间顶点,cost在循环结束后可以正确获得任意两点间的最短路径花费。
//通过p矩阵可以查找任意两点经过的整条路径
//需要使用动态一维数组表示二维矩阵
#include <iostream>
#include <string.h>#include <cstdlib>
using namespace std;
#define MAX_INT 32767
typedef int* Matrix;
typedef struct
{
unsigned int vNum,edgeNum;
char *vex;
Matrix edge;
}Graph;
int locateVex(char *vex,int n,char data)
{
for(int i = 0;i < n;i++)
{
if(vex[i] == data)
return i;
}
return -1;
}
void create(Graph &g)
{
cout<<"vNUm and eNum:\n";
cin>>g.vNum>>g.edgeNum;
g.vex = new char[g.vNum];
g.edge = new int[g.vNum*g.vNum];
for(unsigned int k = 0;k < g.vNum*g.vNum;k++)
{
g.edge[k] = MAX_INT;
}
char es,ee;
int esp,eep,ec;
cout<<"intput vertex:{c}\n";
for(unsigned int i = 0;i < g.vNum;i++)
{
cin>>g.vex[i];
}
cout<<"input edge:{a} {b} {c}\n";
for(unsigned int j = 0;j < g.edgeNum;j++)
{
//scanf("%d,%d,%c",&es,&ee,&ec);
cin>>es>>ee>>ec;
esp = locateVex(g.vex,g.vNum,es);
eep = locateVex(g.vex,g.vNum,ee);
if(-1 == esp || -1 ==eep)
{
cout<<"error!\n";
exit(-1);
}
g.edge[esp*g.vNum + eep] = g.edge[eep*g.vNum + esp] = ec;
}
}
void printGraph(Graph &g)
{
cout<<"vnum:"<<g.vNum<<"edge:"<<g.edgeNum<<endl;
for(unsigned int i = 0;i < g.vNum*g.vNum;i++)
{
if(MAX_INT == g.edge[i])
{
cout<<"x ";
}else
{
cout<<g.edge[i]<<' ';
}
if(i%g.vNum == 4 && i)
{
cout<<endl;
}
}
}
void destroy(Graph &g)
{
delete []g.edge;
delete []g.vex;
}
void printMatrix(Matrix &m,unsigned int n)
{
for(unsigned int i = 0;i < n*n;i++)
{
if(m[i] == MAX_INT)
cout<<"x ";
else
cout<<m[i];
if(i%n == n - 1)
cout<<endl;
}
}
void floyd(Graph &g,Matrix& c,Matrix& p)
{
unsigned int i,j,k;
c = new int[g.vNum*g.vNum];
p = new int[g.vNum*g.vNum];
for(i = 0;i < g.vNum*g.vNum;i++)
{
c[i] = g.edge[i];
p[i] = -1;
}
// printMatrix(c,g.vNum);
// printMatrix(p,g.vNum);
for(k = 0;k < g.vNum;k++)
{
for(i = 0;i < g.vNum;i++)
for(j = 0;j < g.vNum;j++)
{
if(i == j)
continue;
if(c[i*g.vNum+k]+c[k*g.vNum+j] < c[i*g.vNum+j])
{
c[i*g.vNum+j] = c[i*g.vNum+k]+c[k*g.vNum+j];
p[i*g.vNum+j] = k;
cout<<"p["<<i<<"]"<<"["<<j<<"]"<<"="<<k;
}
}
cout<<endl;
}
}
void findPath(char a,char b,Graph &g,Matrix &m)
{
int ap = locateVex(g.vex,g.vNum,a);
int bp = locateVex(g.vex,g.vNum,b);
int e = bp;
cout<<a<<' ';
e = m[ap*g.vNum+bp];
while(e != -1)
{
cout<<g.vex[e]<<' ';
e = m[e*g.vNum+bp];
}
cout<<g.vex[bp];
cout<<endl;
}
int main(int argc,char* argv[])
{
Graph g;
create(g);
printGraph(g);
Matrix p,c;
floyd(g,c,p);
printMatrix(p,g.vNum);
findPath('a','b',g,p);
destroy(g);
}