zoj 2750 Idiomatic Phrases Game

题目大意是,即成语接龙,输入一些成语,每个成语有一个时间t,表示若选择了该成语,则需要时间t才能找到下一个能接上的成语,问从第一个输入的成语走到最后一个输入的成语需要多长时间。

将每个成语当做一个节点建图后,即最短路径问题,从节点i到节点j的时间即i的t。

#include <stdio.h>
#include <string.h>
#define INF 50000
int map[1010][1010],dist[1010],vis[1010],n;
struct idiom
{
	char front[5],back[5];
	int t;
}dic[1010];
void dij(int u)
{
	memset(vis,0,sizeof(vis));
	int i,j,k,v=0,min=INF;
	for(i=0;i<n;i++)
		dist[i]=map[u][i];
	vis[u]=1;
	dist[0]=0;
	for(i=0;i<n-1;i++)
	{
		min=INF;
		for(j=0;j<n;j++)
		{
			if(vis[j]!=1&&dist[j]<min)
			{
				min=dist[j];
				v=j;                     
			}
		}
		vis[v]=1;                         
		//之前一直在运行过程中出问题,后来发现是这里v的原因,若从起点到终点无路径,则v没有被赋值,则有可能读取非法空间,所以在定义v时将它赋值为0
		for(j=0;j<n;j++)
		{
			if(vis[j]!=1&&map[v][j]<INF&&dist[v]+map[v][j]<dist[j])
				dist[j]=dist[v]+map[v][j];
		}
	}
}


int main()
{
	int i,j,t,len,k;
	char s[100];
	while(1)
	{
		scanf("%d",&n);
		if(n==0)
			break;
		for(k=0;k<n;k++)
		{
			scanf("%d%s",&dic[k].t,s);
			len=strlen(s);
			for(i=0,j=len-1;i<4;i++,j--)
			{
				dic[k].front[i]=s[i];
				dic[k].back[3-i]=s[j];
			}
			dic[k].front[4]=dic[k].back[4]='';
		}
		for(i=0;i<n;i++)
		{
			for(j=0;j<n;j++)
			{
				map[i][j]=INF;
				if(i==j)
					continue;
				if(strcmp(dic[i].back,dic[j].front)==0)
					map[i][j]=dic[i].t;
			}
		}
		dij(0);
		if(dist[n-1]==INF)
			printf("-1
");
		else
			printf("%d
",dist[n-1]);
	}
	return 0;
}


 

原文地址:https://www.cnblogs.com/vermouth/p/3710228.html