题意:成语接龙,一个汉字4个字符,注意成语不一定4个汉字,有很多是一句话,所以数组要开的大一点。
想法:单独取出前4和后4个字符,暴力找出其中联系,建边,spfa。
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<map> #define inf 0x7fffffff using namespace std; const int nodes=1000+5; const int edges=20000+50; map<string,int>Mp; int n; struct nodee { int w,begin,end; }shuju[nodes]; struct node { int v,w,next; }e[edges]; int head[nodes],cnt; void Init() { memset(head,-1,sizeof(head)); cnt=0; } void add(int a,int b,int w) { e[cnt].v=b; e[cnt].w=w; e[cnt].next=head[a]; head[a]=cnt++; } int dis[nodes],vis[nodes],num; int spfa() { queue<int>q; while(!q.empty()) q.pop(); for(int i=1;i<=n;i++) { dis[i]=inf; vis[i]=0; } dis[1]=0; vis[1]=1; q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i+1;i=e[i].next) { int v=e[i].v; if(dis[v]>dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; if(!vis[v]) { vis[v]=1; q.push(v); } } } } if(dis[n]!=inf) return dis[n]; return -1; } int main() { while(~scanf("%d",&n),n) { Mp.clear(); Init(); num=0; for(int i=1;i<=n;i++) { int w; char a[1000],b[1000]; scanf("%d%s",&w,a); for(int j=0;j<4;j++) b[j]=a[j]; if(!Mp[b]) Mp[b]=++num; int u=Mp[b]; int len=strlen(a),ll=0; for(int j=len-4;j<len;j++) b[ll++]=a[j]; if(!Mp[b]) Mp[b]=++num; int v=Mp[b]; shuju[i].w=w; shuju[i].begin=u; shuju[i].end=v; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(shuju[i].end==shuju[j].begin) { add(i,j,shuju[i].w); } } } int res=spfa(); printf("%d\n",res); } return 0; }