PTA L2-001 Emergency Rescue (Dijkstra Algorithm Application)

L2-001 Emergency Rescue (25 points)

As the head of a city’s emergency rescue team, you have a special map of the country. On the map, there are multiple scattered cities and some express roads connecting the cities. The number of rescue teams in each city and the length of each expressway connecting the two cities are marked on the map. When other cities have emergency calls to you, your task is to lead your rescue team as soon as possible to the place where the incident occurred, and at the same time, gather as many rescue teams as possible along the way.

Input format:

Enter the first line to give 4 positive integers N, M, S, D, where N (2≤N≤500) is the number of cities. By the way, assume that the number of the city is 0 ~ (N−1); M is fast The number of roads; S is the city number of the departure place; D is the city number of the destination.

The second line gives N positive integers, where the i-th number is the number of rescue teams in the i-th city, and the numbers are separated by spaces. In the subsequent M lines, each line gives information about an express road, namely: city 1, city 2, and the length of the express road, separated by spaces, and the numbers are all integers and do not exceed 500. The input ensures that the rescue is feasible and the optimal solution is unique.

Output format:

The first line outputs the number of shortest paths and the maximum number of rescue teams that can be assembled. The second line outputs the number of the city passed in the path from S to D. The numbers are separated by spaces, and there should be no extra spaces at the end of the output.

Input sample:

4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

Sample output:

2 60
0 1 3

Problem solving

The title requires the shortest path of a single source, but it also needs to calculate the number of shortest paths, the weight of the optimal vertices in the shortest path, and use the num[] array to record the number of shortest paths for each vertex, and the ans[] array to record the optimal vertex weight. , Num[] The array is added when the shortest path takes the equal sign, the specific implementation depends on the code

Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 5e2 + 2;
int G[maxn][maxn];	// 边权重 
int V[maxn];		// 顶点权重 
int dist[maxn], path[maxn];
int num[maxn];		// 记录最短路条数 
int ans[maxn];		// 记录最优顶点权重 
bool vis[maxn];

struct node{
    
    
	int v;
	int w;
};

struct cmp{
    
    
	bool operator () (const node &a, const node &b){
    
    
		return a.w > b.w;
	} 
};

void Dijkstra(int S, int D, int N){
    
    
	memset(dist, 0x3f, sizeof(dist));
	memset(path, -1, sizeof(path));
	dist[S] = 0;
	ans[S] = V[S];
	num[S] = 1;
	vis[S] = true;
	priority_queue<node, vector<node>, cmp> q;
	
	for(int i = 0; i < N; i++){
    
    
		if(!vis[i] && G[S][i]){
    
    
			q.push({
    
    i, G[S][i]});
			dist[i] = G[S][i];
			path[i] = S;
			num[i] = num[S];
			ans[i] = ans[S] + V[i];
		}
	}
	
	while(!q.empty()){
    
    
		int v = q.top().v;
		int w = q.top().w;
		q.pop();
		if(vis[v]) continue;
		vis[v] = true;
		
		for(int i = 0; i < N; i++){
    
    
			if(!vis[i] && G[v][i]){
    
    
				if(dist[v] + G[v][i] < dist[i]){
    
    
					dist[i] = dist[v] + G[v][i];
					q.push({
    
    i, dist[i]});
					num[i] = num[v];	// 单路径时, 接上一个
					ans[i] = ans[v] + V[i];
					path[i] = v;
				} else if(dist[v] + G[v][i] == dist[i]){
    
    
					num[i] += num[v];	// 重复路径时, 增加 
					// ans[i] = max(ans[i], ans[v] + V[i]);
					if(ans[i] < ans[v] + V[i]){
    
    
						ans[i] = ans[v] + V[i];
						path[i] = v;
					}
				}
			}
		}
		if(v == D) return;
	}
}

void Print(int D, int S){
    
    	// 输出最优解 
	if(path[D] == -1 && D == S){
    
    
		cout << D;
		return;
	}
	Print(path[D], S);
	cout << " " << D;
}

int main() {
    
    
	int N, M, S, D;
	cin >> N >> M >> S >> D;
	for(int i = 0; i < N; i++) cin >> V[i];
	
	int v1, v2, w;
	for(int i = 0; i < M; i++){
    
    
		cin >> v1 >> v2 >> w;
		G[v1][v2] = G[v2][v1] = w;
	}
	Dijkstra(S, D, N);
	
	cout << num[D] << " " << ans[D] << endl;
	// for(int i = 0; i < N; i++){
    
    
	//	cout << dist[i] << " " << num[i] << " " << ans[i] << endl;
	// }
	Print(D, S);

	return 0;
}

Guess you like

Origin blog.csdn.net/qq_45349225/article/details/109827099