题意:给你一部字典,上面有n个成语,成语3个字或4个字,每个汉字由四位16进制位表示,现要求从中选一些成语来进行接龙游戏,即后一个成语的第一个字和前一个成语的最后一个字一样,找到一个成语后要过T的时间才能找到下一个成语,要求成语接龙用字典中第一个成语开始,到最后一个成语结束。
题目说的很复杂,其实就是个最短路,判断成语A的末四位和成语B的前四位是否相同,相同则建边,然后就是有向图最短路裸题
#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 1010
#define eps 1e-7
#define INF 0x7FFFFFFF
#define long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct node{
char ss[5];
char ee[5];
int t;
}a[MAXN];
int edge[MAXN][MAXN];
int vis[MAXN];
int dist[MAXN];
int n;
void dijkstra(int v){
int i, j;
vis[v] = 1;
for(i=1;i<=n;i++){
dist[i] = edge[v][i];
}
for(i=0;i<n-1;i++){
int k = -1, temp = INF;
for(j=1;j<=n;j++){
if(!vis[j]&&dist[j]<temp){
temp = dist[j];
k = j;
}
}
if(k==-1) break;
vis[k] = 1;
for(j=1;j<=n;j++){
if(!vis[j]&&edge[k][j]!=INF&&dist[j]>dist[k]+edge[k][j])
dist[j] = dist[k] + edge[k][j];
}
}
}
int main(){
int i, j, k;
char s[30];
while(scanf("%d",&n),n){
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++){
scanf("%d%s",&a[i].t,s);
int l = strlen(s);
for(j=0,k=l-4;j<4;j++,k++){
a[i].ss[j] = s[j];
a[i].ee[j] = s[k];
}
a[i].ss[j] = a[i].ee[j] = '\0';
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
edge[i][j] = INF;
if(strcmp(a[i].ee,a[j].ss)==0){
edge[i][j] = a[i].t;
}
}
}
dijkstra(1);
if(dist[n]!=INF){
printf("%d\n",dist[n]);
}
else printf("-1\n");
}
return 0;
}