最短路问题,只是牵扯到了字符串的操作。题目是中文描述就不多说了。因为这道题不像普通的最短路问题以数字来给地点编号,而是以地点的名称来确定,所以更加结合实际问题,但是又不方便解题。那么应该把地点的名称用数字来编号,把名称转换成编号来解题,这才是关键。


       注意:此题中的路为无向的;如果无法从起点到达终点,输出为-1,这是题目没有说明的;如果起点就是终点,输出为0。此题用C或C++编译器的运行时间比GCC和G++短。


       下面是解题代码:Dijkstra解法

 

  1 #include <stdio.h>
  2 #include <string.h>
  3 #define N 151
  4 #define NAME 31
  5 #define INF 99999999
  6 
  7 int map[N][N];
  8 int dis[N];         //从起点到编号为下标的地点的距离
  9 int flag[N];
 10 char name[N][NAME];
 11 int na;     //站点的个数
 12 int n;      //道路的个数
 13 
 14 void Init();    //初始化
 15 
 16 void Read();    //输入
 17 
 18 int Count(char s[]);    //计算字符串对应的编号
 19 
 20 void Dijkstra();
 21 
 22 int main()
 23 {
 24     while (~scanf("%d", &n))
 25     {
 26         if (n == -1) break;
 27         Init();
 28         Read();
 29         Dijkstra();
 30         if (strcmp(name[1], name[0]) == 0)
 31         {
 32             printf("0\n");
 33             continue;
 34         }
 35         printf("%d\n", dis[1] == INF ? -1 : dis[1]);
 36     }
 37     return 0;
 38 }
 39 
 40 void Init()     //初始化
 41 {
 42     int i, j;
 43     for (i=0; i<N; ++i)
 44     {
 45         for (j=0; j<N; ++j)
 46         {
 47             map[i][j] = INF;
 48         }
 49         dis[i] = INF;
 50         flag[i] = 0;
 51     }
 52     scanf("%s %s", name[0], name[1]);
 53     na = 2;
 54     return;
 55 }
 56 
 57 void Read()     //输入
 58 {
 59     int i;
 60     char sa[NAME], sb[NAME];
 61     int a, b, c;
 62     for (i=0; i<n; ++i)
 63     {
 64         scanf("%s %s %d", sa, sb, &c);
 65         a = Count(sa);
 66         b = Count(sb);
 67         map[a][b] = map[b][a] = c;
 68     }
 69     return;
 70 }
 71 
 72 int Count(char s[])     //计算字符串对应的编号
 73 {
 74     int i;
 75     for (i=0; i<na; ++i)
 76     {
 77         if (strcmp(name[i], s) == 0)
 78         {
 79             return i;
 80         }
 81     }
 82     strcpy(name[na++], s);
 83     return (na - 1);
 84 }
 85 
 86 void Dijkstra()
 87 {
 88     int i, j, k;
 89     int min;
 90     dis[0] = 0;
 91     for (j=0; j<na; ++j)
 92     {
 93         min = INF;
 94         for (i=0; i<na; ++i)
 95         {
 96             if (flag[i] == 0 && min > dis[i])
 97             {
 98                 min = dis[k = i];
 99             }
100         }
101         flag[k] = 1;
102         for (i=0; i<na; ++i)
103         {
104             if (flag[i] == 0 && dis[i] > dis[k] + map[k][i])
105             {
106                 dis[i] = dis[k] + map[k][i];
107             }
108         }
109     }
110     return;
111 }

 

 

       接下来是Floyd解法,比Dijkstra解法耗时长,但是优势在于代码编写简单

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define N 151
 4 #define NAME 31
 5 #define INF 9999999
 6 
 7 int map[N][N];
 8 char name[N][NAME];
 9 int na;     //站点的个数
10 int n;      //道路的个数
11 
12 void Init();    //初始化
13 
14 void Read();    //输入
15 
16 int Count(char s[]);    //计算字符串对应的编号
17 
18 void Floyd();
19 
20 int main()
21 {
22     while (~scanf("%d", &n))
23     {
24         if (n == -1) break;
25         Init();
26         Read();
27         Floyd();
28         if (strcmp(name[1], name[0]) == 0)
29         {
30             printf("0\n");
31             continue;
32         }
33         printf("%d\n", map[0][1] == INF ? -1 : map[0][1]);
34     }
35     return 0;
36 }
37 
38 void Init()     //初始化
39 {
40     int i, j;
41     for (i=0; i<N; ++i)
42     {
43         for (j=0; j<N; ++j)
44         {
45             map[i][j] = INF;
46         }
47     }
48     scanf("%s %s", name[0], name[1]);
49     na = 2;
50     return;
51 }
52 
53 void Read()     //输入
54 {
55     int i;
56     char sa[NAME], sb[NAME];
57     int a, b, c;
58     for (i=0; i<n; ++i)
59     {
60         scanf("%s %s %d", sa, sb, &c);
61         a = Count(sa);
62         b = Count(sb);
63         map[a][b] = map[b][a] = c;
64     }
65     return;
66 }
67 
68 int Count(char s[])     //计算字符串对应的编号
69 {
70     int i;
71     for (i=0; i<na; ++i)
72     {
73         if (strcmp(name[i], s) == 0)
74         {
75             return i;
76         }
77     }
78     strcpy(name[na++], s);
79     return (na - 1);
80 }
81 
82 void Floyd()
83 {
84     int i, j, k;
85     for (k=0; k<na; ++k)
86     {
87         for (i=0; i<na; ++i)
88         {
89             for (j=0; j<na; ++j)
90             {
91                 if (map[i][j] > map[i][k] + map[k][j])
92                 {
93                     map[i][j] = map[i][k] + map[k][j];
94                 }
95             }
96         }
97     }
98     return;
99 }