题目:
5 5 12345978ABCD2341 5 23415608ACBD3412 7 34125678AEFD4123 15 23415673ACC34123 4 41235673FBCD2156 2 20 12345678ABCD 30 DCBF5432167D 0
17 -1
题目大意:
给定一些单词,前一个的尾和后一个的头相同时,才表示他们相连。求从第1个单词到第n个单词的最短路。
如果不能从第1个单词到最后一个单词则直接输出-1.否则输出。
题目分析:
这道题其实抽象一下,其实还是最短路的问题。以其他题目不太一样的地方就在于建边规则发生了变化。之前当给出形如"a b c"的数据的时候,就表示a和b之间存在一条边,他们之间的距离是c。而现在,如果a想要和b项链,那么就必须符合“a的后半部分与b的前半部分相同”。
还需要注意的是:
1)inf 取大一点。这里取到了10亿,即1000000000
2)dijkstra算法里面要对没找到最小点的情况处理一下。否则会RE的。
之前总结的模板可能有点漏洞,这道题用到的dijkstra的模板是比较完善的。。
代码如下:
/*
* hdu_1546.cpp
*
* Created on: 2015年3月27日
* Author: Administrator
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1015;
const int inf = 1000000000;
int s[maxn]; //用来记录某一点是否被访问过
int map[maxn][maxn]; //地图
int dis[maxn]; //从原点到某一个点的最短距离(一开始是估算距离)
int n;
int target;
int val[maxn];
char strss[maxn][maxn];
/**
* 返回从v---->到target的最短路径
*/
int dijkstra(int v) {
int i;
for (i = 1; i <= n; ++i) { //初始化
s[i] = 0; //一开始,所有的点均为被访问过
dis[i] = map[v][i];
}
dis[v] = 0;//***把自己到自己的距离设成0
s[v] = true;//将源点标记为已经访问过..
for (i = 1; i < n; ++i) {
int min = inf;
int pos = -1;
int j;
for (j = 1; j <= n; ++j) { //寻找目前的最短路径的最小点
if (!s[j] && dis[j] < min) {
min = dis[j];
pos = j;
}
}
//****这里一定要对没有找到最小点的情况处理一下.否则有的题目会跪的。例如HDU 1546.
if(pos == -1){//如果诶有找到最小点
break;//则跳出循环
}
s[pos] = 1;
for (j = 1; j <= n; j++) { //遍历u的所有的邻接的边
if (!s[j] && dis[j] > dis[pos] + map[pos][j]) {
dis[j] = dis[pos] + map[pos][j]; //对边进行松弛
}
}
}
return dis[target];
}
int main() {
while (scanf("%d", &n) != EOF, n) {
int i;
for (i = 1; i <= n; ++i) {
scanf("%d %s", &val[i], strss[i]);//把每一个单词的查找时间 及 每个单词的时间输进去
}
int j;
for (i = 1; i <= n; ++i) {
for (j = 1; j <= n; ++j) {
int len = strlen(strss[i]);
/*
if(strss[i][0] == strss[j][len-4] && strss[i][1] == strss[j][len-3] &&strss[i][2] == strss[j][len-2] && strss[i][3] == strss[j][len-1]){
map[i][j] = val[i];
}else{
map[i][j] = inf;
}
*/
/**
* 注意以下的写法和上面的写法的区别在于.上面的写法师用前面来拼接.
* 而题目要求的是向下面哪种用后面来拼接的
*/
if (strss[j][0] == strss[i][len - 4]
&& strss[j][1] == strss[i][len - 3]
&& strss[j][2] == strss[i][len - 2]
&& strss[j][3] == strss[i][len - 1]) {
map[i][j] = val[i];//将a与b拼接,这时候花费的是查找a单词的时间
} else {
map[i][j] = inf;
}
}
}
target = n;
dijkstra(1);
if (n == 1) {//如果节点数是1的时候.
printf("-1\n");//直接输出-1
} else {//否则,如果节点数>1
if(dis[n] == inf){//如果不存在从第一个单词到最后一个单词的拼接方式.(如果不存在从第一个节点到最后一个节点的路径)
printf("-1\n");//则输出-1
}else{//否则
printf("%d\n", dis[n]);//输出从第一个节点到最后一个节点的最短路径
}
}
}
return 0;
}
(dijkstra 1.1)hdu 1546 Idiomatic Phrases Game(dijkstra——当建图规则为:当一个单词的后4个字符和另一个单词的前4个字符一致时才建边,求最短路径)
原文:http://blog.csdn.net/hjd_love_zzt/article/details/44679567