2021-02-18 Luogu P807 Longest Road

Summary:

Spfa template and the difference between spfa and dijskral


Problem Description:

For example, see Luogu P1807 Longest Road


Analysis of Algorithms:

spfa is mainly used to solve the shortest path of a single source point. Compared with the dijskral algorithm, spfa can solve graphs with negative weight edges and no negative rings. But Dijkstra's algorithm is not as efficient as


Code and detailed 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;
	queue<node> 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 spfa()
	{
    
    
		cin >> n >> m;
		s = 1;
		visit.resize(n + 1, false);
		head.resize(n + 1, 0);
		dfs.resize(n + 1,-1);
		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;
		visit[s] = true;
		q.push(node(s, 0));
		while (!q.empty())
		{
    
    
			node temp = q.front();
			q.pop();
			int x = temp.num;
			int d = temp.d;
			visit[x] = false;
			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初始化为正无穷即为求解最长路
				{
    
    
					dfs[y] = dfs[x] + e[i].w;
					if (!visit[y])
					{
    
    
						q.push(node(y, dfs[y]));
						visit[y] = true;
					}
				}
			}
		}
		cout << dfs[n];
	}
};


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

Guess you like

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