1. 程式人生 > >hdoj 2680 Choose the best route

hdoj 2680 Choose the best route

Choose the best route

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 19110    Accepted Submission(s): 6207


 

Problem Description

One day , Kiki wants to visit one of her friends. As she is liable to carsickness , she wants to arrive at her friend’s home as soon as possible . Now give you a map of the city’s traffic route, and the stations which are near Kiki’s home so that she can take. You may suppose Kiki can change the bus at any station. Please find out the least time Kiki needs to spend. To make it easy, if the city have n bus stations ,the stations will been expressed as an integer 1,2,3…n.

 

 

Input

There are several test cases.
Each case begins with three integers n, m and s,(n<1000,m<20000,1=<s<=n) n stands for the number of bus stations in this city and m stands for the number of directed ways between bus stations .(Maybe there are several ways between two bus stations .) s stands for the bus station that near Kiki’s friend’s home.
Then follow m lines ,each line contains three integers p , q , t (0<t<=1000). means from station p to station q there is a way and it will costs t minutes .
Then a line with an integer w(0<w<n), means the number of stations Kiki can take at the beginning. Then follows w integers stands for these stations.

 

 

Output

The output contains one line for each data set : the least time Kiki needs to spend ,if it’s impossible to find such a route ,just output “-1”.

 

 

Sample Input

 

5 8 5 1 2 2 1 5 3 1 3 4 2 4 7 2 5 6 2 3 5 3 5 1 4 5 1 2 2 3 4 3 4 1 2 3 1 3 4 2 3 2 1 1

 

 

Sample Output

 

1 -1

 

 

Author

dandelion

 

題目大意:到一個點有好多條路,有多個起點可以選擇,
要求選出最小的那一條
	解題思路:如果用Dijkstra演算法求出每個起點到終點的距離再比較
就得呼叫w(可選的起點數)次Dijkstra演算法,如果採用Floyd演算法時間複雜度
是O(n^3),也可以用,但是這道題只有一個終點,所以可以把終點當起點
反向呼叫Dijkstra演算法,然後再用一個for迴圈求出終點到各個可選起點的
距離求出最小值,但是這是一個有向圖,反向呼叫的時候需要把圖反著建,所以
輸入時候p和q需要交換位置

#include<stdio.h>
#include<string.h>
#define maxn 0x3f3f3f3f
int map[1010][1010],D[1010],visit[1010],n;
int Dijkstra(int v){
	memset(D,maxn,sizeof(D));
	for(int i=1;i<=n;i++){
		D[i]=map[v][i];
		visit[i]=0;
	}
	visit[v]=1;
	for(int i=2;i<=n;i++){
		int min=maxn;
		int minn=0;
		for(int j=1;j<=n;j++){
			if(D[j]<min&&visit[j]==0){
				min=D[j];
				minn=j;
			}
		}
		visit[minn]=1;
		for(int k=1;k<=n;k++){
			if(D[k]>map[minn][k]+min){
				D[k]=map[minn][k]+min;
			}
		}
	}
}
int main(){
	int m,s,begin,p,q,t,w;
	while(scanf("%d %d %d",&n,&m,&s)!=EOF){
		memset(map,maxn,sizeof(map));
		memset(visit,0,sizeof(visit));
		for(int i=1;i<=n;i++)
		map[i][i]=0;
		for(int i=0;i<m;i++){
			scanf("%d %d %d",&p,&q,&t);
			if(map[q][p]>t){
				map[q][p]=t;//反向建圖 
                //map[p][q]=t;//因為是單向圖,這句話不能加
			}
		}
		Dijkstra(s);
		int min=maxn;
		scanf("%d",&w);
		for(int i=0;i<w;i++){
			scanf("%d",&begin);
			if(D[begin]<min){
				min=D[begin];
			}
		}
		if(min==maxn)
		printf("-1\n");
		else
		printf("%d\n",min);
	}
	return 0;
}