L2-001. 紧急救援 Dijkstra

L2-001. 紧急救援

链接:

https://www.patest.cn/contests/gplt/L2-001

题解:

用一遍dijkstra算法。设立num[i]和w[i]表示从出发点到i结点拥有的路的条数,以及能够找到的救援队的数目~~~当判定dis[u] + e[u][v] < dis[v]的时候,不仅仅要更新dis[v],还要更新num[v] = num[u], w[v] = weight[v] + w[u]; 如果dis[u] + e[u][v] == dis[v],还要更新num[v] += num[u],而且判断一下是否权重w[v]更小,如果更小了就更新w[v] = weight[v] + w[u]; 
再设立一个pre[i]表示最短路径的前一个结点,在dis[u] + e[u][v] <= dis[v]的时候更新pre[v] = u,最后递归打印路径即可

代码:

 1 #include <map>
 2 #include <set>
 3 #include <cmath>
 4 #include <queue>
 5 #include <stack>
 6 #include <cstdio>
 7 #include <string>
 8 #include <vector>
 9 #include <cstring>
10 #include <sstream>
11 #include <iostream>
12 #include <algorithm>
13 #include <functional>
14 using namespace std;
15 #define rep(i,a,n) for (int i=a;i<=n;i++)
16 #define per(i,a,n) for (int i=n;i>=a;i--)
17 #define pb push_back
18 #define mp make_pair
19 #define all(x) (x).begin(),(x).end()
20 #define SZ(x) ((int)(x).size())
21 typedef vector<int> VI;
22 typedef long long ll;
23 typedef pair<int, int> PII;
24 const ll mod = 1e9 + 7;
25 const int inf = 0x3f3f3f3f;
26 const double eps = 1e-7;
27 // head
28 
29 const int maxn = 510;
30 int cost[maxn][maxn];
31 int d[maxn];
32 int used[maxn];
33 int pre[maxn];
34 int V;
35 int N, M, S, D;
36 int weight[maxn], num[maxn], w[maxn];
37 
38 void dijkstra(int s) {
39     memset(d, 0x3f, sizeof(d));
40     memset(used, 0, sizeof(used));
41     memset(pre, -1, sizeof(pre));
42     d[s] = 0;
43     w[s] = weight[s];
44     num[s] = 1;
45 
46     while (1) {
47         int v = -1;
48         rep(u, 0, N - 1) if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
49         if (v == -1) break; used[v] = 1;
50         rep(u, 0, N - 1) if (used[u] == false && cost[u][v] != inf) {
51             if (d[u] > d[v] + cost[v][u]) {
52                 d[u] = d[v] + cost[v][u];
53                 pre[u] = v;
54                 num[u] = num[v];
55                 w[u] = w[v] + weight[u];
56             }
57             else if (d[u] == d[v] + cost[v][u]) {
58                 num[u] += num[v];
59                 if (w[u] < w[v] + weight[u]) {
60                     w[u] = w[v] + weight[u];
61                     pre[u] = v;
62                 }
63             }
64         }
65     }
66 }
67 
68 VI get_path(int t) {
69     VI path;
70     for (; t != -1; t = pre[t]) path.pb(t);
71     reverse(all(path));
72     return path;
73 }
74 
75 int main() {
76     cin >> N >> M >> S >> D;
77     V = N;
78     rep(i, 0, N - 1) cin >> weight[i];
79     memset(cost, 0x3f, sizeof(cost));
80     while (M--) {
81         int a, b, c;
82         cin >> a >> b >> c;
83         cost[a][b] = cost[b][a] = c;
84     }
85     dijkstra(S);
86     cout << num[D] << " " << w[D] << endl;
87     VI path = get_path(D);
88     cout << path[0];
89     rep(i, 1, path.size() - 1) cout << ' ' << path[i];
90     cout << endl;
91     return 0;
92 }

注意:

题目的序号是从0开始的,还有一定要把cost数组初始化为inf

 

posted @ 2017-03-15 11:09  Flowersea  阅读(1738)  评论(0编辑  收藏  举报