2021-02-18 Logu P4779 dijslral algorithm template

Summary:

About the heap optimized version of Dijkstra's algorithm


Problem Description:

See title for details: Luogu P4779


Algorithm Description:

The essence of dijskral algorithm applies greedy strategy and dynamic programming ideas. The principle can be summarized as: the newly generated shortest path is generated by adding an edge to the shortest path that has been generated. Initially, the distance from the starting point s to the starting point s is 0, and each edge added is added by selecting the adjacent edge of a certain point from the edge set of the graph.

In specific implementation, each time a point u with the shortest distance from the starting point s is selected, the distance from u to s is the shortest path selected this time. After selecting the point u with the shortest current distance s, consider the adjacent points of u, that is, consider whether the newly generated shortest path (point) can update the distance from the point where the shortest path is not generated to the starting point s

In summary,
each time a point with the shortest distance from the starting point s is selected, and then the contribution of this point to other points is considered.


Detailed code and comments:

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


Guess you like

Origin blog.csdn.net/sddxszl/article/details/113841523