最短路问题 Dijkstra
题意:
给出n条边,即n个成语,要求是成语之间能首尾相连所化的最短时间,某个起点有可能是无法到达终点的,是一个有向图。
分析:
先处理字符串,存入图中,然后Dijkstra即可。
前两次WA的原因是处理字符串的时候循环变量弄重复了,即:
for(i=0; i<t; i++) { for(j=0; j<t; j++) { e[i][j] = INF; if(i==j) continue; else if(strcmp(dic[i].back, dic[i].front)==0) e[i][j] = dic[i].t; } }
AC代码:
#include <cstdio> #include <cstring> using namespace std; #define MAXN 1010 #define INF 0x3fffffff struct idiom { char front[5],back[5]; int t; }dic[MAXN]; int e[MAXN][MAXN],dist[MAXN],s[MAXN]; void Dijkstra(int n) { int i,j,k; memset(s, 0, sizeof(s)); for(i=0; i<n; i++) dist[i] = e[0][i]; dist[0] = 0; s[0] = 1; for(i=1; i<n; i++) { int min = INF; int u = 0; for(j=0; j<n; j++) { if(!s[j] && dist[j]<min) { min = dist[j]; u = j; } } s[u] = 1; for(k=0; k<n; k++) { if(!s[k] && e[u][k]<INF && dist[k]>e[u][k]+dist[u]) { dist[k] = e[u][k] + dist[u]; } } } if(dist[n-1] == INF) printf("-1\n"); else printf("%d\n", dist[n-1]); } int main() { int t,i,j; char s[100]; while(scanf("%d", &t),t) { memset(dic, 0, sizeof(dic)); for(i=0; i<t; i++) { memset(s, 0, sizeof(s)); scanf("%d%s", &dic[i].t, s); int len = strlen(s); for(j=0; j<4; j++) { dic[i].front[j] = s[j]; dic[i].back[j] = s[len-4+j]; } dic[i].front[4] = dic[i].back[4] = '\0'; } for(i=0; i<t; i++) { for(j=0; j<t; j++) { e[i][j] = INF; if(i==j) continue; else if(strcmp(dic[i].back, dic[j].front)==0) e[i][j] = dic[i].t; } } Dijkstra(t); } return 0; }