最短路问题,只是牵扯到了字符串的操作。题目是中文描述就不多说了。因为这道题不像普通的最短路问题以数字来给地点编号,而是以地点的名称来确定,所以更加结合实际问题,但是又不方便解题。那么应该把地点的名称用数字来编号,把名称转换成编号来解题,这才是关键。
注意:此题中的路为无向的;如果无法从起点到达终点,输出为-1,这是题目没有说明的;如果起点就是终点,输出为0。此题用C或C++编译器的运行时间比GCC和G++短。
下面是解题代码:Dijkstra解法
#include <stdio.h>
#include <string.h>
#define N 151
#define NAME 31
#define INF 99999999
int map[N][N];
int dis[N]; //从起点到编号为下标的地点的距离
int flag[N];
char name[N][NAME];
int na; //站点的个数
int n; //道路的个数
void Init(); //初始化
void Read(); //输入
int Count(char s[]); //计算字符串对应的编号
void Dijkstra();
int main()
{
while (~scanf("%d", &n))
{
if (n == -1) break;
Init();
Read();
Dijkstra();
if (strcmp(name[1], name[0]) == 0)
{
printf("0\n");
continue;
}
printf("%d\n", dis[1] == INF ? -1 : dis[1]);
}
return 0;
}
void Init() //初始化
{
int i, j;
for (i=0; i<N; ++i)
{
for (j=0; j<N; ++j)
{
map[i][j] = INF;
}
dis[i] = INF;
flag[i] = 0;
}
scanf("%s %s", name[0], name[1]);
na = 2;
return;
}
void Read() //输入
{
int i;
char sa[NAME], sb[NAME];
int a, b, c;
for (i=0; i<n; ++i)
{
scanf("%s %s %d", sa, sb, &c);
a = Count(sa);
b = Count(sb);
map[a][b] = map[b][a] = c;
}
return;
}
int Count(char s[]) //计算字符串对应的编号
{
int i;
for (i=0; i<na; ++i)
{
if (strcmp(name[i], s) == 0)
{
return i;
}
}
strcpy(name[na++], s);
return (na - 1);
}
void Dijkstra()
{
int i, j, k;
int min;
dis[0] = 0;
for (j=0; j<na; ++j)
{
min = INF;
for (i=0; i<na; ++i)
{
if (flag[i] == 0 && min > dis[i])
{
min = dis[k = i];
}
}
flag[k] = 1;
for (i=0; i<na; ++i)
{
if (flag[i] == 0 && dis[i] > dis[k] + map[k][i])
{
dis[i] = dis[k] + map[k][i];
}
}
}
return;
}
接下来是Floyd解法,比Dijkstra解法耗时长,但是优势在于代码编写简单
#include <stdio.h>
#include <string.h>
#define N 151
#define NAME 31
#define INF 9999999
int map[N][N];
char name[N][NAME];
int na; //站点的个数
int n; //道路的个数
void Init(); //初始化
void Read(); //输入
int Count(char s[]); //计算字符串对应的编号
void Floyd();
int main()
{
while (~scanf("%d", &n))
{
if (n == -1) break;
Init();
Read();
Floyd();
if (strcmp(name[1], name[0]) == 0)
{
printf("0\n");
continue;
}
printf("%d\n", map[0][1] == INF ? -1 : map[0][1]);
}
return 0;
}
void Init() //初始化
{
int i, j;
for (i=0; i<N; ++i)
{
for (j=0; j<N; ++j)
{
map[i][j] = INF;
}
}
scanf("%s %s", name[0], name[1]);
na = 2;
return;
}
void Read() //输入
{
int i;
char sa[NAME], sb[NAME];
int a, b, c;
for (i=0; i<n; ++i)
{
scanf("%s %s %d", sa, sb, &c);
a = Count(sa);
b = Count(sb);
map[a][b] = map[b][a] = c;
}
return;
}
int Count(char s[]) //计算字符串对应的编号
{
int i;
for (i=0; i<na; ++i)
{
if (strcmp(name[i], s) == 0)
{
return i;
}
}
strcpy(name[na++], s);
return (na - 1);
}
void Floyd()
{
int i, j, k;
for (k=0; k<na; ++k)
{
for (i=0; i<na; ++i)
{
for (j=0; j<na; ++j)
{
if (map[i][j] > map[i][k] + map[k][j])
{
map[i][j] = map[i][k] + map[k][j];
}
}
}
}
return;
}