Hduoj2066【Dijkstra】

/*一个人的旅行
Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20091    Accepted Submission(s): 7015


Problem Description
虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),
很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景
,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,
所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
 
Input
输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。
 

Output
输出草儿能去某个喜欢的城市的最短时间。
 

Sample Input
6 2 3
1 3 5
1 4 7
2 8 12
3 8 4
4 9 12
9 10 2
1 2
8 9 10

Sample Output
9
 
Author
Grass

Source
RPG专场练习赛 
*/
#include<stdio.h>
#include<string.h>
#define Max(A,B)  ( (A) > (B)  ? (A):(B) )
#define Min(A,B)  ( (A) < (B)  ? (A):(B) )
int T, S, D, Road[1010][1010], dis[1010], vist[1010];//road用来保存原始城市数据 dis用来保存每个城市到起点的最小时间
int city1[1010], city2[1010];//保存起点  和终点
const int M = 1000000;
void Dij(int start, int m)// 迪杰特斯拉算法的核心
{
	int  k, temp;
	memset(vist, 0, sizeof(vist));
	for(int i = 1; i <= m; i++)//记录各个城市到起点的初始数据
	dis[i] = Road[start][i];
	vist[start] = 1;//将起点城市标记
	for(int i = 1; i <= m-1; i++)//进行m-1次遍历 为了找到剩下的m-1个点到起点的最小距离
	{
		temp = M;
		for(int j = 1; j <= m; j++)//遍历每个城市,找出最小的距离
		{
			if(!vist[j] && dis[j] < temp)
			{
				temp = dis[j];
				k = j;
			} 
		}
		vist[k] = 1;//将最小距离的城市做上标记
		for(int j = 1; j <= m; j++)//更新每个城市到起点的距离
		if(!vist[j])
		dis[j] = Min(dis[j], dis[k] + Road[k][j]); 
	} 
}
int main()
{
	int min , max,  k, m, n;
	while(scanf("%d%d%d", &T, &S, &D) != EOF)
	{
		for(int i = 0; i < 1001; i++)//对城市之间的距离初始化,城市本身之间的距离为0
		{
			for(int j = 0; j < 1001; j++)
			{
				if(i != j)
				Road[i][j]  =  M;
				else 
				Road[i][j] = Road[j][i] = 0;
			}
		}
		max = 0;//用来记录输入的最大城市的编号
		for(int i = 0; i < T; i++)
		{
			scanf("%d%d%d", &m, &n, &k);
			if(Road[m][n] > k )//如果重复输入了两个城市的距离选择小的
			Road[m][n] = Road[n][m] = k;
			if(Max(m, n) > max)
			max = Max(m,n);
		}
		for(int i = 0; i < S; i++)//输入起点
		scanf("%d", &city1[i]);
		for(int i = 0; i < D; i++)//输入终点
		scanf("%d", &city2[i]);
		min = M;
		for(int i = 0; i < S; i++)//以起点和终点进行遍历
		{
			Dij(city1[i], max);
			for(int j = 0; j < D; j++)
			{
				if(dis[city2[j]] < min)
				min = dis[city2[j]]; //求出最小的时间(距离)
			} 
		} 
		printf("%d\n", min);
	}
	return 0;
}
本题 有个关键,虽然我不太明白为什么,由于i j 变量多次使用 每次用到时需要重新进行定义 ,可以减少内存 ,不然提交会RE。

你可能感兴趣的:(c)