Rescate de emergencia PTA L2-001 (aplicación del algoritmo Dijkstra)

L2-001 Rescate de emergencia (25 puntos)

Como jefe del equipo de rescate de emergencia de una ciudad, tiene un mapa especial del país. En el mapa, hay varias ciudades dispersas y algunas carreteras rápidas que conectan las ciudades. El número de equipos de rescate en cada ciudad y la longitud de cada autopista que conecta las dos ciudades están marcados en el mapa. Cuando otras ciudades tienen llamadas de emergencia, su tarea es llevar a su equipo de rescate lo antes posible al lugar donde ocurrió el incidente y, al mismo tiempo, reunir tantos equipos de rescate como sea posible en el camino.

Formato de entrada:

Ingrese la primera línea para obtener 4 números enteros positivos N, M, S, D, donde N (2≤N≤500) es el número de ciudades. Por cierto, suponga que el número de la ciudad es 0 ~ (N − 1 ); M es rápido El número de carreteras; S es el número de ciudad del lugar de salida; D es el número de ciudad del destino.

La segunda línea da N números enteros positivos, donde el i-ésimo número es el número de equipos de rescate en la i-ésima ciudad, y los números están separados por espacios. En las siguientes líneas M, cada línea proporciona información sobre una vía rápida, a saber: ciudad 1, ciudad 2 y la longitud de la vía rápida, separadas por espacios, y los números son todos enteros y no exceden de 500. La entrada asegura que el rescate sea factible y que la solución óptima sea única.

Formato de salida:

La primera línea muestra el número de caminos más cortos y el número máximo de equipos de rescate que se pueden reunir. La segunda línea da como resultado el número de la ciudad que pasó en el camino de S a D. Los números están separados por espacios y no se permiten espacios adicionales al final de la salida.

Muestra de entrada:

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

Salida de muestra:

2 60
0 1 3

Resolución de problemas

El título requiere la ruta más corta de una sola fuente, pero también necesita calcular la cantidad de rutas más cortas, el peso de los vértices óptimos en la ruta más corta y usar la matriz num [] para registrar la cantidad de rutas más cortas para cada vértice, y la matriz ans [] para registrar el peso óptimo del vértice., Num [] La matriz se agrega cuando la ruta más corta toma el signo igual, la implementación específica depende del código

Código

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

Supongo que te gusta

Origin blog.csdn.net/qq_45349225/article/details/109827099
Recomendado
Clasificación