最短路问题 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;
}
}
错误的地方是,双重循环里,重复比较dic[i].front和dic[i].back,所以WA。
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;
}