hdu-2680 Choose the best route---dijkstra+反向存图或者建立超级源点

题目链接:

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
", ans);
46     }
47     return 0;
48 }