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;
}