题目大意是,即成语接龙,输入一些成语,每个成语有一个时间t,表示若选择了该成语,则需要时间t才能找到下一个能接上的成语,问从第一个输入的成语走到最后一个输入的成语需要多长时间。
将每个成语当做一个节点建图后,即最短路径问题,从节点i到节点j的时间即i的t。
#include <stdio.h> #include <string.h> #define INF 50000 int map[1010][1010],dist[1010],vis[1010],n; struct idiom { char front[5],back[5]; int t; }dic[1010]; void dij(int u) { memset(vis,0,sizeof(vis)); int i,j,k,v=0,min=INF; for(i=0;i<n;i++) dist[i]=map[u][i]; vis[u]=1; dist[0]=0; for(i=0;i<n-1;i++) { min=INF; for(j=0;j<n;j++) { if(vis[j]!=1&&dist[j]<min) { min=dist[j]; v=j; } } vis[v]=1; //之前一直在运行过程中出问题,后来发现是这里v的原因,若从起点到终点无路径,则v没有被赋值,则有可能读取非法空间,所以在定义v时将它赋值为0 for(j=0;j<n;j++) { if(vis[j]!=1&&map[v][j]<INF&&dist[v]+map[v][j]<dist[j]) dist[j]=dist[v]+map[v][j]; } } } int main() { int i,j,t,len,k; char s[100]; while(1) { scanf("%d",&n); if(n==0) break; for(k=0;k<n;k++) { scanf("%d%s",&dic[k].t,s); len=strlen(s); for(i=0,j=len-1;i<4;i++,j--) { dic[k].front[i]=s[i]; dic[k].back[3-i]=s[j]; } dic[k].front[4]=dic[k].back[4]=' '; } for(i=0;i<n;i++) { for(j=0;j<n;j++) { map[i][j]=INF; if(i==j) continue; if(strcmp(dic[i].back,dic[j].front)==0) map[i][j]=dic[i].t; } } dij(0); if(dist[n-1]==INF) printf("-1 "); else printf("%d ",dist[n-1]); } return 0; }