基本想法:
令d [i, j, k]表示从i 到j 的最短路径的长度,其中k 表示该路径中的最大顶点,也就是说d[i,j,k]这条最短路径所通过的中间顶点最大不超过k。
最开始只允许经过1号顶点进行中转,接下来只允许经过1和2号顶点进行中转。。。。允许经过n号所有顶点进行中转,求任意两点之间的最短路径。概况:从i号顶点到j号顶点只经过前k号点的最短路径。也就是两个点之间的距离将会中转所有的顶点的最短距离Floyd-Warshall算法时间复杂度是O(N^3)
Floyd-Warshall算法不能解决带有“负权回路”(或者叫“负权环”的图),因为带有“负权环”的图没有最短路径。
<span style="font-size:18px;">#include<iostream>
using namespace std;
int main()
{
int point;//
cin>>point;//点数
int edgs;
cin>>edgs;//路径数或者边
int ed[10][10];
int infinity=99999999;
for (int i=1;i<=point;i++)//初始化
{
for (int j=1;j<=point;j++)
{
if (i==j)
{
ed[i][j]=0;
}
else
{
ed[i][j]=infinity;
}
}
}
int point1,point2,quanzhi;
for ( i=1;i<=edgs;i++)//输入权值
{
cin>>point1>>point2>>quanzhi;
ed[point1][point2]=quanzhi;
}
for (int k=1;k<=point;k++)//核心思想,中转点
{
for (int p=1;p<=point;p++)
{
for (int q=1;q<=point;q++)
{
if (ed[p][q]>ed[p][k]+ed[k][q])
{
ed[p][q]=ed[p][k]+ed[k][q];
}
}
}
}
for (i=1;i<=point;i++ )
{
for (int j=1;j<=point;j++)
{
cout<<ed[i][j]<<" ";
}
cout<<endl;
}
return 0;
}</span>
输出结果如下图:
打印路径程序:
#include<iostream>
#include<stack>
using namespace std;
int path[10][10];
int point;//
int edgs;
void printPath(int s,int e)
{
stack<int> si;
for (int i=1;i<=point;i++)
{
for (int j=1;j<=point;j++)
{
if (i==s&&j==e)
{
int k =j;
do
{
k=path[i][k];//路径都是相反的存入在path里面
si.push(k);
} while (k!=i);
cout<<si.top();
si.pop();
int len=si.size();
for (int w=0;w<len;w++)
{
cout<<"->"<<si.top();
si.pop();
}
cout<<"->"<<e<<endl;//终点没有在栈里
break;
}
}
}
}
int main()
{
int start,end;
cin>>point;
cin>>edgs;
cin>>start>>end;
int ed[10][10];
int infinity=99999999;
for (int i=1;i<=point;i++)
{
for (int j=1;j<=point;j++)
{
if (i==j)
{
ed[i][j]=0;
}
else
{
ed[i][j]=infinity;
}
path[i][j]=i;
}
}
int point1,point2,quanzhi;
for ( i=1;i<=edgs;i++)
{
cin>>point1>>point2>>quanzhi;
ed[point1][point2]=quanzhi;
}
for (int k=1;k<=point;k++)
{
for (int p=1;p<=point;p++)
{
for (int q=1;q<=point;q++)
{
if (ed[p][q]>ed[p][k]+ed[k][q])
{
ed[p][q]=ed[p][k]+ed[k][q];
path[p][q]=path[k][q];//记录路径
}
}
}
}
for (i=1;i<=point;i++ )
{
for (int j=1;j<=point;j++)
{
cout<<ed[i][j]<<" ";
}
cout<<endl;
}
printPath(start,end);
return 0;
}
输出结果