题意:给你一部字典,上面有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; }
时间: 2024-10-29 12:58:17