题意概括:有N个城市和M条道路,任意两个城市之间都有可能超过一种以上的可能。求任意两个城市之间的最短距离。
解题思路:1:典型的多源最短路径问题。
代码思路:
1:用一个二维数组e来存储任意两个城市之间的距离,用inf = 99999999来初始化存储除一个城市自己到自己之外的所有距离,用int n, m分别作为城市数和道路数。
int e[202][202];
int inf = 99999999, n, m;
2:先输入n, m,分别为城市数和道路数,然后用一个二重for循环来初始化城市之间的距离,如果是一个城市自己到自己,则置为0;否则置为inf。
scanf("%d%d", &n, &m);
for(i = 1; i <= n; i ++)
{
for(j = 1; j <= n; j ++)
{
if(i == j)
{
e[i][j] = 0;
}
else
{
e[i][j] = inf;
}
}
}
3:用一个for循环循环m次,在这个循环里面,每次输入两个城市的标号以及它们之间的距离,并将表示这两个城市之间的距离二维数组e更新为新的距离(如果道路是单向的,只需更新一个e;如果道路是双向的,则需更新两个e,分别是城市a到城市b的距离以及城市b到城市a的距离)。
for(i = 1; i <= m; i ++)
{
scanf("%d%d%d", &a, &b, &c);
if(c < e[a][b])
{
e[a][b] = c;
e[b][a] = c;
}
}
4:然后用三重循环,最外重循环从1到n,表示要经历的中转点;第二层循环表示起始城市;最内层循环表示终止城市。在最内层循环内,用if语句判断从起始城市到终止城市的距离是否大于其经过中转点的距离,如果是,则用两个城市经过中转点的距离代替从起始城市到终止城市的直接距离。
for(k = 1; k <= n; k ++)
{
for(i = 1; i <= n; i ++)
{
for(j = 1; j <= n; j ++)
{
if(e[i][j] > e[i][k] +e[k][j])
{
e[i][j] = e[i][k] + e[k][j];
}
}
}
}
5:输出。输出在二维数组e中从城市a到城市b的距离,即为其最短距离。
printf("%d\n", e[a][b]);
错误原因:此题错了一次。
第一次:1. 输入的问题。 没有考虑清楚题目所说的任意两个城市之间都可以有很多路径。题目的这个描述其实就是说再输入的时候如果两个城市之间有大于1条以上的路径,如果不进行判断,后面的输入就会覆盖前面的输入,导致输入数据有误。而我忽略了这一点,导致后面输入的数据覆盖了前面的数据。应该在输入的时候进行判断,因为此题是求任意两个城市之间的最短距离,因此如果两个城市之间的距离在进行输入时,后面输入的数据小于之前输入的数据时,要更新两个城市之间的距离,否则可以忽略此次输入。
经验总结:1:读清楚题目,充分考虑题目所涵盖的各种情况,尤其是对于“任意”这个词,既包含了1到n,也包含了1到2,2到3......
2:要考虑城市标号是从0开始还是从1开始,这决定了for循环的起始标号。
我的AC代码:
#include<stdio.h>
#include<string.h>
int main(void)
{
int e[202][202];
int inf = 99999999;
int n, m, i, j, k, t1, t2, t3, s, t;
while(scanf("%d%d", &n, &m)!= EOF)
{
memset(e, 0, sizeof(e));
for(i = 0; i <= n - 1; i ++)
{
for(j = 0; j <= n - 1; j ++)
{
if(i ==j)
{
e[i][j] = 0;
}
else
{
e[i][j] = inf;
}
}
}
for(i = 1; i <= m; i ++)
{
scanf("%d%d%d", &t1, &t2, &t3);
{
if(t3 < e[t1][t2])
{
e[t1][t2] =t3;
e[t2][t1] =t3;
}
}
}
for(k = 0; k <= n- 1; k ++)
{
for(i = 0; i <= n - 1; i ++)
{
for(j = 0; j <= n- 1; j ++)
{
if(e[i][j] > e[i][k] +e[k][j])
{
e[i][j] = e[i][k] + e[k][j];
}
}
}
}
scanf("%d%d", &s, &t);
if(e[s][t] != inf)
{
printf("%d\n", e[s][t]);
}
else
{
printf("-1\n");
}
}
return 0;
}