https://pintia.cn/problem-sets/994805046380707840/problems/994805073643683840
shortest path
Because it also requires the number of shortest paths and the maximum number of rescuers
For each node and the previous node of each node, the ideal method is to add three record information in the structure, just like the fifth problem of Blue Bridge Cup. This problem is to add the information of the number of the shortest path, the current maximum number of rescue teams and the previous node of each node.
But the way we save graph is not to save points, but to save edges, so we can only open an additional array tot [] to record the number of shortest paths from the starting point to each point; another array sum [] to record the current maximum number of rescue teams at each point; another pre [] to record the previous node of each node.
#include <iostream> #include <queue> #include <cstring> #include <stack> #include <algorithm> using namespace std; const int maxn = 505; int N, M, s, e; // nums: number of people at each point, d: distance from each point to the origin int nums[maxn], dist[maxn]; // tot: the number of the shortest path from start to point i, sum: the number of people from start to point i int tot[maxn], sum[maxn]; int pre[maxn]; bool vis[maxn]; vector<pair<int, int> > E[maxn]; void dijkstra() { priority_queue<pair<int, int> > Q; // Q.top(). First = the distance from the point of Q.top().second is the number of q.top() // Because pair is sorted by the first latitude first, pair.first needs to be dist //Initialization dist[s] = 0; Q.push({-dist[s], s}); // Slack while (!Q.empty()) { // Head is always the closest point to the far point. Use head to relax other points every time. // Use head to relax all the outlets connected with head every time int head = Q.top().second;// head: the number of the point with the shortest dist (closest to the starting point) Q.pop(); if (vis[head]) continue; vis[head] = 1; for (int i = 0; i < E[head].size(); i ++ ) { int v = E[head][i].first; // The number of the edge connected to the head int curdist = E[head][i].second; // Distance from the start point of the edge connected to the head // Because head is connected to v, head can be used to relax the dist of v // Different from the common shortest path problem, the common shortest path does not need to consider the same distance when relaxation occurs // Equal distance when slack: update the number of paths that can be reached, and the maximum number of rescues // No need to join the team because dist is not updated if (dist[v] == dist[head] + curdist) { tot[v] += tot[head]; sum[v] = max(sum[v], sum[head] + nums[v]); pre[v] = head; } // Can relax: update the distance, update the number of paths that can be reached, and update the maximum number of rescues if (dist[v] > dist[head] + curdist) { dist[v] = dist[head] + curdist; tot[v] = tot[head]; sum[v] = sum[head] + nums[v]; pre[v] = head; Q.push({-dist[v], v}); } } } } void output(int x) { vector<int> path; for (; x!= -1; x = pre[x]) path.push_back(x); reverse(path.begin(), path.end()); int n = path.size(); // The last space of PAT's question must not be added // Prevent using size()-1 for (int i = 0; i < n; i ++) cout << path[i] << " \n"[i==n-1]; } int main () { memset(dist, 0x3f, sizeof dist); memset(pre, -1, sizeof pre); cin >> N >> M >> s >> e; for (int i = 0; i < N; i ++ ) cin >> nums[i]; for (int i = 0; i < M; i ++ ) { int a, b, c; cin >> a >> b >> c; E[a].push_back({b, c}); E[b].push_back({a, c}); } tot[s] = 1; sum[s] = nums[s]; dijkstra(); cout << tot[e] << " " << sum[e] << endl; output(e); return 0; }