1. 程式人生 > >一個人的旅行 HDU杭電2066【dijkstra算法 || SPFA】

一個人的旅行 HDU杭電2066【dijkstra算法 || SPFA】

個數 strong -s stdio.h rip include tom trac 第一次

http://acm.hdu.edu.cn/showproblem.php?

pid=2066


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

//Dijkstra

#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
int map[1010][1010];
int dis[1010];
bool used[1010];
int n;
int i,j;
void dijkstra()
{
	int i,j;
	memset(used,0,sizeof(used));
	for(i=0;i<=1000;++i)
		dis[i]=INF;
	int pos;
	for(i=0;i<=1000;++i)//第一次給dis賦值 
	{
		dis[i]=map[0][i];
	}
	dis[0]=0;
	used[0]=1;
	for(i=0;i<1000;++i)//最多執行n次 
	{
		int min=INF;
		for(j=0;j<=1000;++j)
		{
			if(!used[j]&&dis[j]<min)
			{
				min=dis[j];
				pos=j;
			}
		} 
		used[pos]=1;
		dis[pos]=min;
		for(j=0;j<=1000;++j)//把dis數組更新。也叫松弛
		{
			if(!used[j]&&dis[j]>map[pos][j]+dis[pos])
			{
				dis[j]=map[pos][j]+dis[pos];
			}
		}
	}
}
int main()
{
	int m,T;
	int u,v,w;
	int temp;
	int a[1010],b[1010];
	while(~scanf("%d%d%d",&n,&m,&T))
	{		
		for(i=0;i<=1000;++i)
      		for(j=0;j<=i;++j)
        		map[i][j]=map[j][i]=INF;
		for(i=1;i<=n;++i)
		{
			scanf("%d%d%d",&u,&v,&w);
			if(map[u][v]>w)
				map[u][v]=map[v][u]=w;
		}
		for(i=1;i<=m;++i)
		{
			scanf("%d",&temp);
			map[0][temp]=0;
		}
		dijkstra();
		int min=INF;
		for(i=1;i<=T;++i)
		{
			scanf("%d",&temp);
			if(dis[temp]<min) min=dis[temp];
		}
		printf("%d\n",min);
	}
	return 0;
}

//SPFS


#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 1100
#define MAXM 10100
#define INF 0x3f3f3f3f
using namespace std;
struct Edge
{
	int u, v, w;
	int next;//下一個結構體變量的下標 
}edge[MAXM];
int head[MAXN];//下標為起點u,值為相應結構體下標 
int vis[MAXN];//推斷是否增加隊列了 
int num;
int low[MAXN];//存最短路徑 
void Add_Edge(int u, int v, int w)//加邊 
{
	Edge E={u, v, w, head[u]};//初始化結構體 
	edge[num]=E;//直接賦值 
	head[u]=num++;
}
void SPFA(int s)
{
	int i, j;
	queue<int> Q;
	memset(low, INF, sizeof(low)); 
	memset(vis, 0, sizeof(vis));	
	vis[s] = 1;
	low[s]=0; 
	Q.push(s);
	while(!Q.empty())
	{
		int u=Q.front();
		Q.pop();
		vis[u]=0;//出隊列了,不在隊列就變成0 
		for(j = head[u]; j != -1; j = edge[j].next)
		{
			int v = edge[j].v;
			if(low[v] > low[u] + edge[j].w)
			{
				low[v] = low[u] + edge[j].w;
				if(!vis[v])				 
			 	{
			 		vis[v]=1;
			 		Q.push(v);
			 	}
			}
		}
	}
}
int main()
{
	int u, v, w;
	int S,E,M,N,s,e;
	while(~scanf("%d%d%d", &N, &S,&E))
	{
		memset(head, -1, sizeof(head));
		num=0;
		for(int i=1; i <= N; ++i)
		{
			scanf("%d%d%d", &u, &v, &w);
			Add_Edge(u, v, w);
			Add_Edge(v, u, w);//無向邊 
		}		
		while(S--)
		{
			scanf("%d",&s);
			Add_Edge(0,s,0);//建萬能源點		
		}
		SPFA(0);
		int min=INF;
		while(E--)
		{
			scanf("%d",&e);
			if(min>low[e]) min=low[e];
		}
		printf("%d\n",min);
	}
	return 0;
}


一個人的旅行 HDU杭電2066【dijkstra算法 || SPFA】