迪杰斯特拉单源最短路算法。对成语进行预处理。做出邻接矩阵即可。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn = 1005; int c[maxn], len[maxn], cost[maxn][maxn], flag[maxn], e[maxn]; char s[maxn][100]; int main() { int n, i, j, ii; while (~scanf("%d", &n)) { if (n == 0) break; for (i = 0; i < n; i++) scanf("%d%s", &c[i], s[i]); for (i = 0; i < n; i++) len[i] = strlen(s[i]); memset(flag, 0, sizeof(flag)); for (i = 0; i <= n; i++) for (j = 0; j <= n; j++) cost[i][j] = 999999999; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (i != j&&s[j][0] == s[i][len[i] - 4] && s[j][1] == s[i][len[i] - 3] && s[j][2] == s[i][len[i] - 2] && s[j][3] == s[i][len[i] - 1]) cost[i][j] = c[i]; } } for (i = 0; i < n; i++) e[i] = cost[0][i]; e[0] = 0; flag[0] = 1; int x, uu; for (ii = 0; ii < n - 1; ii++) { int minn = 999999999; uu = 0; for (i = 0; i < n; i++) { if (!flag[i] && e[i] < minn) { x = i; minn = e[i]; uu = 1; } } if (!uu) continue; flag[x] = 1; for (i = 0; i < n; i++) if (!flag[i] && cost[x][i] != 999999999 && e[x] + cost[x][i] < e[i]) e[i] = e[x] + cost[x][i]; } if (e[n - 1] != 999999999) printf("%d ", e[n - 1]); else printf("-1 "); } return 0; }