有两种方案:①bellman_ford ②bellman_ford的优化算法spfa
直接放代码
①
#include <iostream>
using namespace std;
struct edge
{
int x, y, w;
}es[50010];
int distence[1510];
//bellman_ford这个算法其实有点类似于Floyd算法,设定起点单源
//,然后通过边的遍历来获得一个中转点,经过n轮的全边遍历,
//最长能够形成n+1个节点的最长边(在无环的情况下当然是不可能的)
int main() {
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
cin >> es[i].x >> es[i].y >> es[i].w;
}
distence[1] = 0;
for (int i = 2; i <= n; i++)
{
distence[i] = -1000000000;
}
bool flag;//用于判断该次流程是否有进行更新,若无更新,即已得到该图的最短路径
for (int i = 0; i < n; i++)
{
flag = false;
for (int j = 0; j < m; j++)
{
int x = es[j].x;
int y = es[j].y;
int w = es[j].w;
if (distence[x] != -1000000000) {
distence[y] = distence[x] + w > distence[y] ? distence[x] + w : distence[y];
flag = true;
}
}
if (!flag) {
break;
}
}
if (distence[n] != -1000000000) {
cout << distence[n] << endl;
}
else {
cout << -1 << endl;
}
return 0;
}
②
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct edge
{
int x, y, w;
}es[50010];
vector<int> map[1510];
queue<int> q;
bool visted[1510] = { 0 };
int dis[1510] ;
//bellman_ford的缺点在于对节点的无脑扫描,会有很多重复的操作,而spfa则是
//,每次更新操作之后,才会以更新的点为起点,在进行扫描,看看是否能够进行伸缩
int main() {
int n,m;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
cin >> es[i].x >> es[i].y >> es[i].w;
map[es[i].x].push_back(i);
}
dis[1] = 0;
for (int i = 2; i < 1510; i++)
{
dis[i] = -1000000;
}
q.push(1);
visted[1] = 1;
while (!q.empty())
{
int x = q.front();
q.pop();
visted[x] = 0;
int en = 0;
int to = 0;
int w = 0;
for (int i = 0; i < map[x].size(); i++)
{
en = map[x][i];
to = es[en].y;
w = es[en].w;
if (dis[to] < dis[x] + w) {
dis[to] = dis[x] + w;
if (!visted[to]) {
q.push(to);
}
}
}
}
if (dis[n] == -1000000) {
cout << -1 << endl;
}
else {
cout << dis[n];
}
return 0;
}