推荐看这篇文章
Bellman-Ford算法可以判断负环,计算权值有负数的情况,
SPFA算法只能判断负环,不能输出负圈。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
typedef long long ll;
const int maxn = 1000 + 10;
const int INF = 1 << 25;
int T, n, m, cases;
struct edge
{
int u, v, w;
};
edge a[maxn];
int path[maxn], d[maxn];
bool Bellman(int v0)
{
for(int i = 0; i < n; i++)
d[i] = INF, path[i] = -1;
d[v0] = 0;
for(int i = 0; i < n; i++)//迭代n次,如果第n次还在更新,说明有负环
{
bool update = 0;
for(int j = 0; j < m; j++)
{
int x = a[j].u, y = a[j].v;
//cout<<x<<" "<<y<<" "<<a[j].w<<endl;
if(d[x] < INF && d[x] + a[j].w < d[y])
{
d[y] = d[x] + a[j].w;
path[y] = x;
update = 1;
if(i == n - 1)//说明第n次还在更新
{
return true;//返回真,真的存在负环
}
}
}
if(!update)
break;//如果没更新了,说明已经松弛完毕
}
for(int i = 0; i < n; i++)
{
if(i == v0)
continue;
printf("从%d到%d距离是:%2d ", v0, i, d[i]);
stack<int>q;
int x = i;
while(path[x] != -1)
{
q.push(x);
x = path[x];
}
cout<<v0;
while(!q.empty())
{
cout<<"->"<<q.top();
q.pop();
}
cout<<endl;
}
return false;
}
int main()
{
cin >> n >> m;
for(int i = 0; i < m; i++)
cin >> a[i].u >> a[i].v >> a[i].w;
if(Bellman(0))
cout<<"存在负环"<<endl;
else
cout<<"不存在负环"<<endl;
return 0;
}