zoj 2750 Idiomatic Phrases Game【最短路】

题目连接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1750

题目大意:

给出n个字典,接下来n行第一个是查看字典的时间,后面接的是这个成语,要求把每条成语连起来,以成语接龙的形式。字符串代表成语,如果第一个串的后4个字符与第二个串的前4个字符相等,那么说明它们能连起来,用的时间是第一个成语的时间,每组数据输入的第一个成语和最后一个成语为已知的。输出最少的时间,不能完成则输出-1.

思路:

转换成最短路。每个成语代表一个节点,如果两个成语能连起来那么就在这两个节点之间连一条路,权值为第一个成语的时间,求第一个成语到最后一条成语的最短路径。

代码:

#include<stdio.h>
#include<string.h>
#include<limits.h>

#define MAXN 1001
struct dict {
	char front[5], end[5];
	int time;
};

struct dict dic[MAXN];
int map[MAXN][MAXN];
int s[MAXN];
int dist[MAXN];
int n;

void dijkstra()
{
	for(int i = 0; i < n; i++) {
		s[i] = 0;
		dist[i] = map[0][i];
	}
	s[0] = 1;
	dist[0] = 0;
	int u = 0;
	for(int i = 0; i < n-1; i++) {
		int min = INT_MAX;
		for(int j = 0; j < n; j++) {
			if(s[j] == 0 && dist[j] < min) {
				u = j;
				min = dist[j];
			}
		}
		s[u] = 1;
		for(int j = 0; j < n; j++) {
			if(s[j] == 0 && map[u][j] < INT_MAX && dist[u] + map[u][j] < dist[j]) {
				dist[j] = dist[u] + map[u][j];
			}
		}
	}
}

int main()
{
	while(scanf("%d", &n) != EOF) {
		if(n == 0) break;
		for(int i = 0; i < n; i++) {
			char str[100];
			scanf("%d %s", &dic[i].time, str);
			int len = strlen( str );
			for(int j = 0, k = len - 1; j < 4; j++, k--) {
				dic[i].front[j] = str[j];
				dic[i].end[3-j] = str[k];
			}
			dic[i].front[4] = dic[i].end[4] = '\0';
		}
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				map[i][j] = INT_MAX;
				if(i == j) continue;
				if(strcmp(dic[i].end, dic[j].front) == 0) {
					map[i][j] = dic[i].time;
				}
			}
		}
		dijkstra();
		if(dist[n-1] == INT_MAX) {
			printf("-1\n");
		} else {
			printf("%d\n", dist[n-1]);
		}
	}
	return 0;
}

 

posted @ 2012-11-13 23:56  小猴子、  阅读(547)  评论(0编辑  收藏  举报