2021-02-18 Plantilla de algoritmo dijslral Logu P4779

Resumen:

Acerca de la versión optimizada de pila del algoritmo de Dijkstra


Descripción del problema:

Ver título para más detalles: Luogu P4779


Descripción del algoritmo:

La esencia del algoritmo dijskral aplica una estrategia codiciosa e ideas de programación dinámica. El principio se puede resumir como: la ruta más corta recién generada se genera agregando un borde a la ruta más corta ya generada. Inicialmente, la distancia desde el punto inicial s hasta el punto inicial s es 0, y cada borde agregado se agrega seleccionando el borde adyacente de un cierto punto del conjunto de bordes del gráfico.

En una implementación específica, cada vez que se selecciona un punto u con la distancia más corta desde el punto de inicio s, la distancia desde u hasta s es la ruta más corta seleccionada esta vez. Después de seleccionar el punto u con la distancia actual más corta s, considere los puntos adyacentes de u, es decir, considere si la ruta más corta recién generada (punto) puede actualizar la distancia desde el punto donde no se genera la ruta más corta hasta el punto de inicio s

En resumen,
cada vez que se selecciona un punto con la distancia más corta desde el punto de partida s, se considera la contribución de este punto a otros puntos.


Código detallado y comentarios:

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <algorithm>
#include <stack>
#include <queue>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
struct edge{
    
    
	int to;
	int next;
	int w;
};
struct node{
    
    
	int num;
	int d;
	node(int _num = 0, int _d = 0) :num(_num), d(_d) {
    
    }
	bool operator()(const node& n1, const  node& n2)
	{
    
     
		return n1.d > n2.d;//">"表示建立小根堆,"<"表示建立大根堆
	}
};

class Solution{
    
    
public:
	int n, m, s;  //分别为点数,边数,起点
	int cnt = 0;  //记录当前输入到第几条边,用于链式前向星建图
	//链式前向星建图
	vector<int> head;
	vector<edge> e;
	//记录是否已经产生最短路径
	vector<bool> visit;
	//堆优化
	priority_queue<node,vector<node>,node> q;  //自定的变量使用std::堆的方法
	/*
	priority_queue<自定义的结构体的名称,vector<自定的结构体的名称>,自定的结构体的名称> q;
	自定的结构体中必须重载"()"操作符
	*/
	//保存的最终答案
	vector<int> dfs;  //distance from source

	//链式前向星建图模板
	inline void add_edge(int u, int v, int w)
	{
    
    
		cnt++;
		e[cnt].to = v;
		e[cnt].w = w;
		e[cnt].next = head[u];
		head[u] = cnt;
	}

	void dijskral()
	{
    
    
		cin >> n >> m >> s;
		visit.resize(n + 1, false);
		head.resize(n + 1, 0);
		dfs.resize(n + 1, 2147483647);
		e.resize(m + 1);
		for (int i = 1; i <= m; ++i)
		{
    
    
			int u, v, w;
			cin >> u >> v >> w;
			add_edge(u, v, w);
		}
		dfs[s] = 0;
		q.push(node(s,0));
		while (!q.empty())
		{
    
    
			node temp = q.top();
			q.pop();
			int x = temp.num;
			int d = temp.d;
			if (visit[x])
				continue;
			visit[x] = true;
			for (int i = head[x]; i != 0; i = e[i].next)
			{
    
    
				int y = e[i].to;
				if (dfs[y] > dfs[x] + e[i].w)
				{
    
    
					dfs[y] = dfs[x] + e[i].w;
					if (!visit[y])
						q.push(node(y, dfs[y]));
				}
			}
		}
		for (int i = 1; i <= n; ++i)
			cout << dfs[i] << " ";
	}
};


int main() {
    
    
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	Solution s;
	s.dijskral();
}


Supongo que te gusta

Origin blog.csdn.net/sddxszl/article/details/113841523
Recomendado
Clasificación