问题概述:成都的大街上有n个路口,标号为1的路口是学校所在地,标号为n的路口是家所在地,m则表示在成都有几条路,输入3个整数a、b、c表示从a路口到b路口有路可走,且要花费c分钟,求从学校到家最短时间
输入样例: 对应输出:
3 3 2
1 2 5
2 3 5
3 1 2
Floyd算法:
功能:可以求出任意两点的最短路
适用:有向图 √ 无向图 √ 权值为正 √ 权值为负 ×
复杂度:n³(复杂度很高)
核心:通过枚举n个点利用DP的思想来更新最短距离,假设当前枚举到第k个点,对于任意的两个点i和j,如果i-k可以相连且k-j可以相连,那么就有"dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);",只要枚举完n个点,就说明已经完全更新完所有两点直间的最短路
本质是个DP,代码里有注释
#include<stdio.h>
#include<limits.h>
int main(void)
{
int a, b, c, i, k, j, n, m, d[105][105];
while(scanf("%d%d", &n, &m), n!=0 || m!=0)
{
for(i=1;i<=n;i++)
{
d[i][i] = 0;
for(j=1;j<=i-1;j++)
d[i][j] = d[j][i] = INT_MAX; /*没有路的地方设为权值设为INT_MAX*/
}
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
d[a][b] = d[b][a] = c;
}
for(k=1;k<=n;k++) /*从i走到j是否经过k点(可以更快),这个k一定要在最外层循环,这样可以保证对于k-1,i到j的路程已经最优*/
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(d[i][k]!=INT_MAX && d[k][j]!=INT_MAX && d[i][k]+d[k][j]<d[i][j])
d[i][j] = d[i][k]+d[k][j];
}
}
}
printf("%d\n", d[1][n]);
}
return 0;
}