链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1546
题目:
5 5 12345978ABCD2341 5 23415608ACBD3412 7 34125678AEFD4123 15 23415673ACC34123 4 41235673FBCD2156 2 20 12345678ABCD 30 DCBF5432167D 0
17 -1
题目大意:
给出n个“成语”, 这写成语至少由3个“汉字”组成,所谓的“汉字”,是指4个连续的16进制数字(1~9, A~F)。
以第一个成语作为起点,最后一个作为终点, 需要找出一个序列,这个序列的前一个成语的最后一个“汉字”与后一个成语的第一个“汉字”是相同的,求最少花费时间。
分析与总结:
建好图之后就是最基本的最短路问题。
在输入时,对于每个成语只需要保存第一个汉字与最后一个汉字即可。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<utility> using namespace std; typedef pair<int,int>pii; priority_queue<pii,vector<pii>,greater<pii> >q; const int INF = 0x7fffffff; const int VN = 1005; struct Edge{int v,next,w;}E[VN*VN]; struct Idiom{ char beg[5], end[5]; }arr[VN]; int n,size; int head[VN]; int d[VN]; int cost[VN]; void init(){ size=0; memset(head, -1, sizeof(head)); while(!q.empty())q.pop(); } void addEdge(int u,int v,int w){ E[size].v=v, E[size].w=w; E[size].next = head[u]; head[u] = size++; } void Dijkstra(int src){ for(int i=1; i<=n; ++i) d[i] = INF; d[src] = 0; q.push(make_pair(d[src],src)); while(!q.empty()){ pii x = q.top(); q.pop(); int u = x.second; if(d[u] != x.first) continue; for(int e=head[u]; e!=-1; e=E[e].next){ int tmp = d[u] + E[e].w; if(d[E[e].v] > tmp){ d[E[e].v] = tmp; q.push(make_pair(tmp, E[e].v)); } } } } int main(){ int w; char str[100]; while(scanf("%d",&n)&&n){ init(); for(int i=1; i<=n; ++i){ scanf("%d %s",&cost[i],str); for(int j=0; j<5; ++j) arr[i].beg[j]=str[j]; int len = strlen(str); for(int j=len-4,k=0; j<len; ++j,++k) arr[i].end[k]=str[j]; arr[i].end[4] = arr[i].beg[4] = 0; } for(int i=1; i<n; ++i){ for(int j=1; j<=n; ++j){ if(strcmp(arr[i].end, arr[j].beg)==0) addEdge(i,j,cost[i]); } } Dijkstra(1); if(d[n]!=INF) printf("%d\n", d[n]); else puts("-1"); } return 0; }
—— 生命的意义,在于赋予它意义。
原创 http://blog.csdn.net/shuangde800 , By D_Double (转载请标明)