这题的关键是把车站的名字转化为点的编号。我用的是map。声明一个map<string,int> st,然后按照字符串出现的次序给st赋值。例如:st[s1]=2;代表这字符串s1出现的次序是2。出现过的已经被标记。不会重复。接下来用模版就好。不过有一点要注意的是当起点和终点一样是,要输出0。

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<map> 6 #include<algorithm> 7 using namespace std; 8 9 //在主函数中Map初始化为INF 10 const int N = 160, INF =0x3f3f3f3f; 11 int dist[N], Map[N][N], pre[N]; 12 //dist表示i到s的最短距离,Map记录图,pre记录前驱 13 bool p[N];//标记点是否已经被选择 14 void Dijkstra(int n,int s) 15 { 16 int i,j,k, MIN; 17 for(i=1; i<=n; i++) //初始化 18 { 19 p[i]=0; 20 if(i!=s) 21 { 22 dist[i]= Map[s][i]; 23 pre[i]=s; 24 } 25 } 26 dist[s]=0; 27 p[s]=1; 28 for(i=1; i<n; i++) //循环n-1次 29 { 30 MIN=INF; 31 k=0; 32 for(j=1; j<=n; j++) 33 { 34 if(!p[j]&&dist[j]<MIN) 35 { 36 MIN= dist[j]; 37 k=j; 38 } 39 } 40 if(!k) return ;//没有点可以扩展 41 p[k]=1; //将k从Vb中除去,加入Va 42 for(j=1; j<=n; j++) 43 { 44 if(!p[j]&&Map[k][j]!=INF&&dist[j]>dist[k]+Map[k][j]) 45 { 46 dist[j]= dist[k] + Map[k][j]; 47 pre[j]=k; 48 } 49 } 50 } 51 } 52 void init() 53 { 54 for(int i=0;i<=N;i++) 55 for(int j=0;j<=N;j++) 56 Map[i][j]=INF; 57 } 58 map<string,int> st; 59 int main() 60 { 61 //freopen("test.txt","r",stdin); 62 int n,i,j,k; 63 char s1[35],s2[35]; 64 while(scanf("%d",&n)!=EOF) 65 { 66 if(n==-1) break; 67 scanf("%s%s",s1,s2); 68 if(strcmp(s1,s2)==0) { 69 for(i=0;i<n;i++) 70 scanf("%s%s%d",s1,s2,&k); 71 printf("0 "); 72 continue; 73 } 74 init(); 75 st.clear(); 76 st[s1]=1; st[s2]=2; 77 j=2; 78 for(i=0;i<n;i++) 79 { 80 scanf("%s%s%d",s1,s2,&k); 81 if(st[s1]==0) st[s1]=++j; 82 if(st[s2]==0) st[s2]=++j; 83 if(st[s1]==st[s2]) continue; 84 Map[st[s2]][st[s1]]=Map[st[s1]][st[s2]]=min(k,Map[st[s1]][st[s2]]); 85 } 86 Dijkstra(j,1); 87 if(dist[2]<INF) 88 printf("%d ",dist[2]); 89 else printf("-1 "); 90 91 } 92 return 0; 93 }