题目:http://http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1750。。他的意思就是:给出n个字典,接下来n行第一个是查看字典的时间,后面接的是这个成语,要求把每条成语连起来,以成语接龙的形式。字符串代表成语,如果第一个串的后4个字符与第二个串的前4个字符相等,那么说明它们能连起来,用的时间是第一个成语的时间,每组数据输入的第一个成语和最后一个成语为已知的。输出最少的时间,不能完成则输出-1.。
具体思路:主要就是这里的时间就是相当于距离,而怎样把这个距离转化出来就是我们要做的,把这个距离解出来就是完全的最短路问题,(dijkstra).
所以这里的转化就成了关键。
具体看代码。当时我也是看了别人的解题思路才懂得!!我原来一直以为这题很简单,但还是弄了好久。。。。看了还得继续加把劲咯。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
//#include<climits>
#define MAXN 1001
const int MAX=100000001//这里的最大值有时要注意下!!(若用INT_MAX,则必须加(#include<climits>头文件)否则就会超时。)
using namespace std;
struct point
{
char star[5],end[5];
int time ;
};
struct point dis[MAXN];
bool flag[MAXN];
int map[MAXN][MAXN];
int dic[MAXN];
int n;
void dijstra()
{
int i,j,k,minx;
memset(flag,false,sizeof(flag));
for(i=0; i<n; i++)
{
dic[i]=map[0][i];
}
flag[0]=true;
dic[0]=0;
for(j=0; j<n-1; j++)
{
minx=MAX;
k=0;
for(i=0; i<n; i++)
{
if(!flag[i]&&minx>dic[i])
{
minx=dic[i];
k=i;
}
}
flag[k]=true;
for(i=0; i<n; i++)
{
if(!flag[i]&&dic[i]>dic[k]+map[k][i])
dic[i]=dic[k]+map[k][i];
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
char str[1001];
for(int i=0; i<n; i++)
{
int len;
scanf("%d%s",&dis[i].time,&str);
len=strlen(str);
for(int j=0,k=len-1; j<4; j++,k--)//以下几行就是此题的关键所在,
{
dis[i].star[j]=str[j];
dis[i].end[3-j]=str[k];
}
dis[i].star[4]=dis[i].end[4]='\0';//尤其注意这一行,很多时候就会遗漏。造成错误。。
}
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
map[i][j]=MAX;
if(i==j)continue;
if(strcmp(dis[i].end,dis[j].star)==0)//当可以找到相等时就直接得出时间(“距离")。。
{
map[i][j]=dis[i].time;
}
}
}
dijstra();
if(dic[n-1]==MAX)
{
printf("-1\n");
}
else
printf("%d\n",dic[n-1]);
}
return 0;
}