HDU-2680(dijkstra+邻接矩阵+优先队列)
Choose the best route
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11655 Accepted Submission(s): 3791
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.
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
题意:kiki是个人,想要去朋友家玩。要最短时间到朋友家。看输入:每组case中,第一排分别是总点数n,总边数m,朋友家在哪个点s。下面的m行分别是点a到点b有权值w的有向边。后面是kiki能从num个点开始。下面一行有num个数,分别是能从哪num个点开始。求最快到朋友家的时间。有重边,有向边。
思路:反向最短路。输入的时候注意判重边。从朋友家做为源点。dijkstra第k次加入的点就是离朋友家第k近的点。先记录能从哪些点开始。每次加入一个点,就判断是否能从这开始。如果能就输出。找不到就-1。加边的时候注意,因为是有向边,而且我们需要反向最短路,所以要反向建边。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define maxn 1010 8 #define maxm 20010 9 #define INF 200000000 10 int n, m, s; 11 int u, v, wa; 12 int number, start; 13 //点序号从0开始,边序号从0开始 14 int w[maxn][maxn]; 15 bool visit[maxn]; 16 int d[maxn]; 17 bool choos[maxn];//记录kiki能否从该点出发 18 19 struct point{ 20 int u, d; 21 point(int index, int dist):u(index),d(dist){} 22 bool operator < (const point& p1) const{ 23 return d > p1.d; 24 } 25 }; 26 27 priority_queue<point> q; 28 29 void ini(){ 30 memset(choos, false, sizeof(choos)); 31 for(int i = 0; i < n; i++){ 32 for (int j = 0; j < n; j++){ 33 w[i][j] = INF; 34 } 35 } 36 } 37 38 //邻接矩阵+优先队列 39 int dijkstra(int s){ 40 memset(visit, false, sizeof(visit)); 41 for(int i = 0; i < n; i++){ 42 d[i] = INF; 43 } 44 d[s] = 0; 45 while(q.size()) q.pop(); 46 q.push((point){s, 0}); 47 48 while(!q.empty()){//利用优先队列来找到最短路径的点 49 point p1 = q.top(); 50 q.pop(); 51 52 if(visit[p1.u]) continue;//如果该点已有最短路径 53 visit[p1.u] = true; 54 55 if(choos[p1.u])//检查该点是否是kiki能出发的点 56 return d[p1.u]; 57 58 for(int i = 0; i < n; i++){//用该点把n个点松弛一遍 59 if(d[i] > d[p1.u] + w[p1.u][i]){ 60 d[i] = d[p1.u] + w[p1.u][i]; 61 q.push((point){i, d[i]});//新松驰的点入队 62 } 63 64 } 65 } 66 return -1;//不可达 67 } 68 69 int main() 70 { 71 while(~scanf("%d%d%d", &n, &m, &s)){ 72 s--;//点序号从0开始 73 ini(); 74 75 for(int i = 0; i < m; i++){ 76 scanf("%d%d%d", &u, &v, &wa); 77 u--; 78 v--; 79 if(wa < w[v][u])//注意判重,选权值最小的边 80 w[v][u] = wa;//反向建边 81 } 82 83 scanf("%d", &number); 84 for (int i = 0; i < number; i++){ 85 scanf("%d", &start); 86 choos[start-1] = true; 87 } 88 89 printf("%d\n", dijkstra(s)); 90 } 91 return 0; 92 }

浙公网安备 33010602011771号