求最短路径当中形式最好看的算法。也很容易理解。
核心思想:通过加入k顶点,然后求出各顶点到其余顶点中间结点编号不大于k的最小值。
DP思想体现:froyd是一个经典的DP求解最短路径的算法,采用自底向上方式计算路径。这里这个ki(i=1——n)不妨看成是一个阶段,每一个ki加入就是在每一个阶段做出决策:从i到j的最短路径上是否包含结点k。
上一个状态:Dk-1【i】【j】
当前状态:Dk【i】【j】
状态转移方程:Dk【i】【j】=min{Dk-1【i】【j】,Dk-1【i】【k】+Dk-1【k】【j】},1=<K<=n
D0【i】【j】={ (1)w(i,j) 当<i,j>属于E,
(2)inf(无穷大) 反之 }
#include<iostream>
using namespace std;
#define inf 0x6ffffff
int map[300][300];
int n;
void floyd()
{
for(int k=1;k<=n;k++) //核心思想的体现,第1重循环加入k,是为了在加入k之后更新之后的所有路径
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(map[i][k]!=inf && map[k][j]!=inf && map[i][j]>map[i][k]+map[k][j])
map[i][j]=map[i][k]+map[k][j];
}
}
int main()
{
int tt,m,s,t;
cin>>tt ;
while(tt--)
{
scanf("%d%d%d%d",&n,&m,&s,&t);
int a,b,w;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)// //memset(mm,inf,sizeof(mm));不能用memset,我勒个去
map[i][j]=inf;
for(int i=1;i<=m;i++)//
{
scanf("%d%d%d",&a,&b,&w);
map[a][b]=w;
map[b][a]=w;//
}
floyd();
printf("s->t's min road: % d\n",map[s][t]);
}
system("pause");
return 0;}