1. 程式人生 > >【最短路】HDU2680:Choose the best route

【最短路】HDU2680:Choose the best route

namespace src this test least rri sed chan 路徑

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 題意:給定一個有向圖,多個起點,一個終點,求起點到終點的最短路。 註意:圖是有向圖,兩個車站之間可能有多條道路。開始時我一直當做無向圖做,結果WA了幾次之後,看Discuss裏說是有向圖。郁悶啊。。。 分析: 思路一:因為有多個起點可以選擇,但只有一個終點,所以自己可以再加上一個點作為起點,編號為0,這個點和題中給的那些起點之間的距離為0。這樣題目就轉化為了求單源最短路徑問題。 思路二:反向圖。把終點作為反向圖的起點,題中的起點作為要到達的終點,每條路的起點和終點交換。然後用Dijkstra求單源最短路,記錄最小值即可。 思路一代碼: 技術分享圖片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 1050;
 7 const int INF = 1<<30;
 8 int mapp[maxn][maxn];
 9 int vis[maxn],dis[maxn];
10 int sta[maxn],endd[maxn];
11 int n,m,s;
12 void init()
13 {
14     int i,j;
15     for(i=0;i<maxn;i++)
16     {
17         for(j=0;j<maxn;j++)
18         {
19             mapp[i][j]=INF;
20         }
21         mapp[i][i]=0;
22     }
23 }
24 void Dijkstra()
25 {
26     int pos,minn;
27     memset(vis,0,sizeof(vis));
28     vis[0]=1;
29     dis[0]=1;
30     for(int i=1;i<=n;i++)
31         dis[i]=mapp[0][i];
32     for(int i=1;i<=n;i++)
33     {
34         minn=INF;
35         for(int j=1;j<=n;j++)
36         {
37             if(!vis[j]&&dis[j]<minn)
38             {
39                 pos=j;
40                 minn=dis[j];
41             }
42         }
43         vis[pos]=1;
44         for(int j=1;j<=n;j++)
45             dis[j]=min(dis[j],dis[pos]+mapp[pos][j]);
46     }
47 }
48 
49 int main()
50 {
51     int x,y,z,w;
52     while(scanf("%d%d%d",&n,&m,&s)!=EOF)
53     {
54         init();
55         for(int i=0;i<m;i++)
56         {
57             scanf("%d%d%d",&x,&y,&z);
58             if(mapp[x][y]>z)
59                 mapp[x][y]=z;
60         }
61         scanf("%d",&w);
62         for(int i=0;i<w;i++)
63         {
64             scanf("%d",&sta[i]);
65             mapp[0][sta[i]]=0;
66         }
67         Dijkstra();
68         if(dis[s]<INF)
69             cout << dis[s] << endl;
70         else
71             cout << "-1" << endl;
72     }
73     return 0;
74 }
View Code

思路二代碼

技術分享圖片
 1 #include<stdio.h>  
 2 #include<string.h>  
 3 #define INF 1<<26  
 4 const int N = 1e3 + 10;  
 5 int w[N][N], d[N];  
 6   
 7 void Dijkstra(int n, int u)  
 8 {  
 9     int vis[N], i;  
10     memset(vis, 0, sizeof(vis));  
11     for(i = 1; i <= n; i++)  
12         d[i] = INF;  
13     d[u] = 0;  
14     for(i = 1; i <= n; i++)  
15     {  
16         int x = u, temp = INF;  
17         for(int y = 1; y <= n; y++)  
18             if(!vis[y] && d[y] < temp)  
19                 temp = d[x = y];  
20         if(temp == INF) break;  
21         vis[x] = 1;  
22         for(int y = 1; y <= n; y++)  
23             if(d[y] > d[x] + w[x][y])  
24                 d[y] = d[x] + w[x][y];  
25     }  
26 }  
27   
28 int main()  
29 {  
30     int n, m, des, i, j;  
31     while(~scanf("%d%d%d",&n, &m, &des))  
32     {  
33         for(i = 1; i <= n; i++)  
34             for(j = 1; j <= n; j++)  
35             {  
36                 if(i == j)  
37                     w[i][j] = 0;  
38                 else  
39                     w[i][j] = INF;  
40             }  
41         int a, b, c;  
42         for(i = 0; i < m; i++)  
43         {  
44             scanf("%d%d%d",&a, &b,&c);  
45             if(c < w[b][a])  
46                 w[b][a] = c;  
47             //路也反向  
48         }  
49         Dijkstra(n, des); //終點作為起點  
50         int num, Min_path = INF, p;  
51         scanf("%d",&num);  
52         for(i = 0; i < num; i++)  
53         {  
54             scanf("%d",&p);  
55             if(d[p] < Min_path)  
56                 Min_path = d[p]; //記錄最小值  
57         }  
58         if(Min_path < INF)  
59             printf("%d\n",Min_path);  
60         else  
61             printf("-1\n");  
62     }  
63     return 0;  
64 }  
View Code

【最短路】HDU2680:Choose the best route