题目还是典型的求最短路问题,套用模板即可,但是如何将字符型的站点名转换为数字,这是一个问题。
此处,采用一个二维字符数组(name[ ][ ])储存站点,起点站对应数字1,终点站对应数字2,接着判断新输入的站点是否已出现过,如果没有出现过,则对应第几个新出现的。如此循环。
代码如下:
#include<stdio.h>
#include<string.h>
//定义一个足够大的数表示无穷大,用来初始化邻接矩阵
#define MAX 0x3f3f3f3f
/*m:结点(即公交站点)数目;邻接矩阵map数组;
标记数组(vis[ ]),用来标记结点是否访问过;
权值数组(dist[ ]),储存最短路的权值*/
int m,map[155][155],vis[155],dist[155];
//Dijkstra算法---求最短路
int Dijkstra(int point)
{
int i,j,dir,min;
/*初始化标记数组(vis[ ])和权值数组(dist[ ]),
标记数组初始化为零表示未访问过,*/
for(i=1;i<=m;i++)
{
vis[i]=0;
dist[i]=map[point][i];
}
//标记第一个结点
vis[point]=1;
dist[point]=0;
//遍历所有结点
for(i=1;i<=m;i++)
{
min=MAX;
//在未访问点中找到最小的权值点
for(j=1;j<=m;j++)
{
if(vis[j]==0&&min>dist[j])
{
dir=j;//记录该点
min=dist[j];//更新
}
}
//如果最小权值依然是无穷大,则说明起点与终点之间不存在最短路
if(min==MAX)
break;
vis[dir]=1;//标记该点已经访问过
//更新权值数组
for(j=1;j<=m;j++)
{
if(vis[j]==0&&dist[j]>dist[dir]+map[dir][j])
{
dist[j]=dist[dir]+map[dir][j];
}
}
}
return dist[2];
}
int main()
{
int i,j,k,n,t;
/*两个一维字符数组用来临时储存每次输入的站名,
二维字符数组用来永久储存出现的站名,只储存一次,不重复储存*/
char str1[31],str2[31],name[155][31];
while(scanf("%d",&n)&&n!=-1)
{
//初始化邻接矩阵map
memset(map,MAX,sizeof(map));
//记录起始站和终点站,同时将起始站对应数字1,终点站对应数字2
scanf("%s %s",&name[1],&name[2]);
//注意初始m的值
for(i=0,m=2;i<n;i++)
{
scanf("%s %s %d",str1,str2,&t);
//在出现过的站点中查询,刚刚输入的第一个站点是否出现过
for(j=1;j<=m;j++)
{
if(strcmp(str1,name[j])==0) break;
}
/*如果查询完所有已记录的站点后未站点相同的(即j>m),
则说明刚刚输入的是一个新站点,记录该站点*/
if(j>m)
strcpy(name[++m],str1);
//查询第二个站点
for(k=1;k<=m;k++)
{
if(strcmp(str2,name[k])==0) break;
}
if(k>m)
strcpy(name[++m],str2);
//将相应的权值储存在邻接 矩阵中
if(t<map[j][k])
{
map[j][k]=map[k][j]=t;
}
}
//如果起始站与终点站相同,输出应该是零
if(strcmp(name[1],name[2])==0)
printf("0\n");
else
{
//如果起始站与终点站的最短路的权值为无穷大,则终点站不可到达
if(Dijkstra(1)>=MAX)
printf("-1\n");
else
printf("%d\n",Dijkstra(1));
}
}
return 0;
}