2021-02-19 The shortest path (reverse construction Tuluogu P1629)

Summary:

Application of the shortest path of single source point


Brief description of the problem:

Find the shortest path from one point to other points and the size of the shortest path from other points to a certain point (the characteristic is that reverse mapping is required).


Original link: Luogu P1629


Analysis of Algorithms:

According to the requirements of the subject, the shortest path from the starting point to other points is required first, so the dijskral algorithm of the shortest path from the single source point is used. And because all paths are one-way paths, the length of the round-trip path is different.

In order to find the distance from point 2 to n-1 to point 1, the reverse mapping method can be used.


Code and detailed comments:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#pragma warning(disable:4996)
using namespace std;
#define INF 2147483647

struct edge {
    
    
	int to;
	int next;
	int w;
 };

struct Node {
    
    
	int pos;
	int w;
	Node(int _pos=0, int _w=0) :pos(_pos), w(_w) {
    
    }
	bool operator()(Node& n1, Node& n2) {
    
    
		return n1.w > n2.w; //大于号是小根
	}
};
int n, m;  //保存点数和边数
class Solution {
    
    
public:
	Solution() {
    
    
		head.resize(n + 1, 0);
		e.resize(m + 1);
		visit.resize(n + 1, false);
		dfs.resize(n + 1, INF);
	}
	int cnt=0;//标记边数
	//链表前向星建图
	vector<int> head;
	vector<edge> e;

	//保存单源点距离
	vector<int> dfs;
	//保存是否被访问过
	vector<int> visit;
	//堆优化
	priority_queue<Node, vector<Node>, Node> q;
	//加边函数,链式前向星加边
	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()
	{
    
    
		int s = 1;
		dfs[s] = 0;
		q.push(Node(s, 0));
		while (!q.empty())
		{
    
    
			Node temp = q.top();
			q.pop();
			int pos = temp.pos;
			int d = temp.w;
			if (visit[pos])
				continue;
			visit[pos] = true;
			for (int i = head[pos]; i != 0; i = e[i].next)
			{
    
    
				int y = e[i].to;
				if (dfs[y] > dfs[pos] + e[i].w)
				{
    
    
					dfs[y] = dfs[pos] + e[i].w;
					if (!visit[y])
						q.push(Node(y, dfs[y]));
				}
			}
		}
	}
};


int main()
{
    
    
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	cin >> n >> m;
	Solution s1;
	Solution s2;
	for (int i = 1; i <= m; ++i)
	{
    
    
		int u, v, w;
		cin >> u>> v>> w;
		s1.add_edge(u, v, w);
		s2.add_edge(v, u, w);
	}
	s1.dijskral();
	s2.dijskral();
	int ans = 0;
	for (int i = 1; i <= n; ++i) {
    
    
		ans += s1.dfs[i] + s2.dfs[i];
	}
	cout << ans;
	return 0;
}

Guess you like

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