Implementación de cola prioritaria plantilla Dijie Tesla

  Dijkstra sigue siendo el algoritmo de ruta más corta más utilizado. El código escrito en el estudio anterior de estructura de datos es muy redundante y no puedo recordarlo. Si tiene tiempo hoy, ¡elaboremos una plantilla concisa!
  El método de implementación corresponde a la cola de prioridad y la plantilla incluye el método de mapeo (de hecho, cualquier tipo de método está bien). Este artículo utiliza:

vector< unordered_map<int, int>> graph(n); // 本质是邻接表

  La plantilla es la siguiente

void DIJ() {
    
    
	/* 建图,建图方式有几种,尽量使用邻接表
	 *	1.vector<vector<int>> graph(n) // 临界矩阵
	 *	2.vector<unordered_map<int,int>> // 邻接表,map中first代表指向,second代表权值
	*/ 
	// 假设有vector<vector<int>>  edges提供边的信息,[1,2,3]代表1->2,权值为3
	vector<unordered_map<int, int>> graph(n);
	for (int i=0; i<edges.size(); i++) {
    
    
		int u = edges[i][0];
		int v = edges[i][1];
		int w = edges[i][2];
		graph[u-1][v-1] = w; // -1的原因是索引从0开始
		graph[v-1][u-1] = w; // 看清问题是单向图还是双向图,决定了写几个
	}
	
	vector<int> dis(n, INT_MAX);
	priority_queue<pair<int, int>, vector<pair<int, int> > > q;
	// 起点编号设置为start
	dis[start] = 0;
	q.push(start, 0);
	while (!q.empty()) {
    
    
		pair<int, int> tp = q.top();
		int id = tp.first;
		int distance = tp.second;
		q.pop();
		// 这里用指针吧,用graph[id][i].first会报错,不知道为啥
		for (auto it=graph[id].begin(); it != graph[id].end(); it++) {
    
    
			int new_id = it->first;
			int new_distance = it->second;
			if (dis[id]+new_distance < dis[new_id]) {
    
    
				dis[new_id] = dis[id] + new_distance;
				q.push(make_pair(new_id, -dis[new_id])); // 传入负值,实现从小到大排列 
			}
		}
	}
}
// dis数组中得到的就是起点到各个节点的最短距离了,如果不达就会是INT_MAX

  Simplemente diga que no practique el estilo falso, ¡probemos la plantilla con dos preguntas de muestra!

Ejercicio 1: P1339 [USACO09OCT] Ola de calor G

P1339 [USACO09OCT] Ola de calor G

El código de CA es el siguiente:

#include<bits/stdc++.h>
using namespace std;

int main(void) {
    
    
	int n,m,s,t;
	cin >> n >> m >> s >> t;
	vector<unordered_map<int,int> > graph(n);
	for (int i=0; i<m; i++) {
    
    
		int u,v,w;
		cin >> u >> v >>w;
		graph[u-1][v-1] = w;
		graph[v-1][u-1] = w;
	}
	vector<int> dis(n, INT_MAX);
	priority_queue<pair<int, int>, vector<pair<int, int>>> q;
	dis[s-1] = 0;
	q.push(make_pair(s-1,0));
	while (!q.empty()) {
    
    
		pair<int, int> tp = q.top();
		int id = tp.first;
		int distance = tp.second;
		q.pop();
		for (auto it=graph[id].begin(); it != graph[id].end(); it++) {
    
    
			int new_id = it->first;
			int new_distance = it->second;
			if (dis[id] + new_distance < dis[new_id]) {
    
    
				dis[new_id] = dis[id] + new_distance;
				q.push(make_pair(new_id, -dis[new_id]));
			}
		}
	}
	cout << dis[t-1];
	return 0;
}

Ejercicio 2: P3371 【Plantilla】 Ruta más corta de origen único (versión debilitada)

P3371 [Plantilla] Ruta más corta de fuente única (versión debilitada)
  De hecho, este código no pasó completamente la prueba, pero fue escrito de acuerdo con la plantilla. Puede pasar la muestra, no sé qué está pasando, por favor ayúdeme a responder las preguntas de los dioses que pasan. Adjunte el código primero, ¿tal vez suceda después?

el código se muestra a continuación:

#include<bits/stdc++.h>
using namespace std;
int main(void) {
    
    
	int n, m, s;
	cin >> n >> m >> s;
	vector<unordered_map<int, int>> graph(n);
	for (int i=0; i<m; i++) {
    
    
		int u,v,w;
		cin >> u >> v >> w;
		graph[u-1][v-1] = w;
	}
	vector<int> dis(n, INT_MAX);
	priority_queue<pair<int,int>,vector<pair<int,int>>> q;
	dis[s-1] = 0;
	q.push(make_pair(s-1, 0));
	while (!q.empty()) {
    
    
		pair<int, int> pa = q.top();
		int id = pa.first;
		int distance = pa.second;
		q.pop();
		for (auto it=graph[id].begin(); it!=graph[id].end(); it++) {
    
    
			int new_id = it->first;
			int new_distance = it->second;
			if (dis[id]+new_distance < dis[new_id]) {
    
    
				dis[new_id] = dis[id]+new_distance;
				q.push(make_pair(new_id, -dis[new_id]));
			}
		}
	}
	for (int i=0; i<n; i++) {
    
    
		if (i != n-1)
			cout << dis[i] << " ";
		else
			cout << dis[i];
	}
	return 0;
}

  De hecho, el tema del gráfico real DIJ es solo una parte, así que domine parte por parte, esperando resolver el gran problema lentamente ¡hhh!

Materiales de referencia:
explicación detallada del algoritmo de Dijkstra + plantilla + preguntas de muestra

Supongo que te gusta

Origin blog.csdn.net/gls_nuaa/article/details/115057519
Recomendado
Clasificación