#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MAX 100000000
struct bus
{
int id;
bus * next[54];
}root;
int busid, dis[155][155], d[155], n;
int getid(char *s)
{
int i, j, k, l;
bus *p = &root, *q;
l = strlen(s);
for(i = 0; i < l; ++i)
{
if(s[i] >= 97 && s[i] <= 122)
k = s[i] - 'a';
else
{
k = s[i] - 'A';
k += 26;
}
if(p->next[k] == NULL)
{
q = (bus *)malloc(sizeof(root));
for(j = 0; j < 54; ++j)
q->next[j] = NULL;
q->id = 0;
p->next[k] = q;
p = q;
}
else
p = p->next[k];
}
if(p->id == 0)
p->id = ++busid;
return p->id;
}
void dij()
{
int i, j, k, vis[200] = {0};
vis[1] = 1;
for(i = 1; i <= busid; ++i)
d[i] = dis[1][i];
for(i = 1; i < busid; ++i)
{
int min = MAX;
k = 0;
for(j = 1; j <= busid; ++j)
{
if( !vis[j] && d[j] < min)
{
min = d[j];
k = j;
}
}
if(k == 0 )
return ;
vis[k] = 1;
for(j = 1; j <= busid; ++j)
{
if(!vis[j] && dis[k][j] < MAX && d[j] > d[k] + dis[k][j])
d[j] = d[k] + dis[k][j];
}
}
}
int main()
{
int i, j, k;
char s1[35], e1[35];
while(scanf("%d", &n) != EOF)//输入n
{
if(n == -1)
break;
for(i = 1; i <= 151; ++i)//初始化
for(j = 1; j <= 151; ++j)
{
if(j != i)
dis[i][j] = MAX;
else
dis[i][j] = 0;
}
busid = 0;//车站个数
scanf("%s%s", s1, e1);//输入起点和终点
int ok = 0;//标记起点和终点是否相同
if(strcmp(s1, e1) == 0)
ok = 1;
for(i = 0; i < 54; ++i)
root.next[i] = NULL;
getid(s1);//将起点的编号为1
getid(e1);//终点编号为2
for(i = 0; i < n; ++i)
{
int temp;
scanf("%s%s %d", s1, e1, &temp);
j = getid(s1);
k = getid(e1);
if(temp < dis[j][k])//重复选取最短的时间
dis[j][k] = dis[k][j] = temp;
getchar();
}
if(ok)
{
printf("0\n");
continue;
}
dij();
if(d[2] == MAX)
printf("-1\n");
else
printf("%d\n", d[2]);
}
return 0;
}
题意:题意很明显。
思路:这里用字典树对每个车站进行编号,然后记录路径长度,最后用迪杰斯特拉求出最短的路径,这里要注意的是起点和终点有可能是一样的输出0,其次就是车站起点和终点可以互换。