摘要:
spfa算法模板
问题描述:
[洛谷P1807最长路](https://www.luogu.com.cn/problem/P1807)代码以及详细注释:
#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;
}