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