1. 程式人生 > >hdu-2680 Choose the best route---dijkstra+反向存圖或者建立超級源點

hdu-2680 Choose the best route---dijkstra+反向存圖或者建立超級源點

min name 最小 dijk AS names oos == 鏈接

題目鏈接:

http://acm.hdu.edu.cn/showproblem.php?pid=2680

題目大意:

給你一個有向圖,一個起點集合,一個終點,求最短路

解題思路:

1.自己多加一個超級源點,把起點集合連接到超級源點上,然後將起點與超級源點的集合的路徑長度設為0,這樣就稱為一個n+1個點的單源最短路算法。。。。。

2.反向圖+終點的Dijkstra,然後記錄最小值。

註意:重邊處理

思路1:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1000
+ 10; 5 const int INF = 0x3f3f3f3f; 6 int Map[maxn][maxn]; 7 int n, m, s; 8 int d[maxn], v[maxn]; 9 void dijkstra() 10 { 11 memset(v, 0, sizeof(v)); 12 for(int i = 0; i <= n; i++)d[i] = INF; 13 d[0] = 0;//源點是0 14 for(int i = 0; i <= n; i++)//n+1個點,循環n+1次 15 { 16 int x = 0, m = INF;
17 for(int j = 1; j <= n; j++)if(!v[j] && d[j] < m)m = d[x = j]; 18 v[x] = 1; 19 for(int j = 1; j <= n; j++) 20 { 21 d[j] = min(d[j], d[x] + Map[x][j]); 22 } 23 } 24 if(d[s] == INF)cout<<"-1"<<endl; 25 else cout<<d[s]<<endl;
26 } 27 int main() 28 { 29 while(cin >> n >> m >> s) 30 { 31 int u, v, w; 32 memset(Map, INF, sizeof(Map)); 33 while(m--) 34 { 35 scanf("%d%d%d", &u, &v, &w); 36 Map[u][v] = min(Map[u][v], w);//註意重邊 37 } 38 scanf("%d", &w); 39 while(w--) 40 { 41 scanf("%d", &u); 42 Map[0][u] = 0;//建立超級源點0 43 } 44 dijkstra(); 45 } 46 return 0; 47 }

思路2:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1000 + 10;
 5 const int INF = 0x3f3f3f3f;
 6 int Map[maxn][maxn];
 7 int n, m, s;
 8 int d[maxn], v[maxn];
 9 void dijkstra()
10 {
11     memset(v, 0, sizeof(v));
12     for(int i = 0; i <= n; i++)d[i] = INF;
13     d[s] = 0;
14     for(int i = 0; i < n; i++)
15     {
16         int x = 0, m = INF;
17         for(int j = 1; j <= n; j++)if(!v[j] && d[j] < m)m = d[x = j];
18         v[x] = 1;
19         for(int j = 1; j <= n; j++)
20         {
21             d[j] = min(d[j], d[x] + Map[x][j]);
22         }
23     }
24 }
25 int main()
26 {
27     while(cin >> n >> m >> s)
28     {
29         int u, v, w;
30         memset(Map, INF, sizeof(Map));
31         while(m--)
32         {
33             scanf("%d%d%d", &u, &v, &w);
34             Map[v][u] = min(Map[v][u], w);//反向建圖
35         }
36         dijkstra();
37         scanf("%d", &w);
38         int ans = INF;
39         while(w--)
40         {
41             scanf("%d", &u);
42             ans = min(ans, d[u]);
43         }
44         if(ans == INF)ans = -1;
45         printf("%d\n", ans);
46     }
47     return 0;
48 }

hdu-2680 Choose the best route---dijkstra+反向存圖或者建立超級源點