L2-001 emergency rescue (25 points)

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;
}

Posted by imamferianto on Fri, 06 Dec 2019 17:59:20 -0800