1、有向图的存储:
用边集数组存储一个有向图
class Edge
{
public:
int u;
int v;
int weight;
};
Edge edge[maxn << 1];
void InsertEdge(int u, int v, int w)
{
edge[++cnt].u = u;
edge[cnt].v = v;
edge[cnt].weight = w;
}
void CreateGraph()
{
int u, v, w;
cout << "请输入结点数:" << endl;
cin >> n;
cout << "请输入边数:" << endl;
cin >> m;
cout << "请依次输入边的两个顶点和权值:" << endl;
for (int i = 1; i <= m; i++)
{
cin >> u >> v >> w;
InsertEdge(u, v, w);
}
}
2、对每条边进行松弛操作以更新最小距离,执行n-1次,只要有一次不成立,没有负环
选择一个点作为源点,初始化距离为无穷大, 源点距离为0,进入n-1次循环
定义一个bool类型变量记录每次循环的更新情况;
遍历所有的边,如果邻接点的距离小于结点距离+对应边的权值,更新邻接点最小距离,并标记,若遍历完所有的边仍无更新,没有负环。
memset(dist, 0x3f3f3f3f, sizeof(dist));
dist[u] = 0;
for (int i = 1; i < n; i++)
{
bool flag = false;
for (int j = 1; j <= m; j++)
{
if (dist[edge[j].v] > dist[edge[j].u] + edge[j].weight)
{
dist[edge[j].v] = dist[edge[j].u] + edge[j].weight;
flag = true;
}
}
if (!flag)
{
return false;
}
}
3、再执行一次,若能更新,有负环;反之,没有负环
for (int j = 1; j <= m; j++)
{
if (dist[edge[j].v] > dist[edge[j].u] + edge[j].weight)
{
return true;
}
}
return false;
整体代码实现:
#include <iostream>
using namespace std;
#define maxn 100
int n, m;
int cnt;
int dist[maxn];
class Edge
{
public:
int u;
int v;
int weight;
};
Edge edge[maxn << 1];
void InsertEdge(int u, int v, int w)
{
edge[++cnt].u = u;
edge[cnt].v = v;
edge[cnt].weight = w;
}
void CreateGraph()
{
int u, v, w;
cout << "请输入结点数:" << endl;
cin >> n;
cout << "请输入边数:" << endl;
cin >> m;
cout << "请依次输入边的两个顶点和权值:" << endl;
for (int i = 1; i <= m; i++)
{
cin >> u >> v >> w;
InsertEdge(u, v, w);
}
}
bool Bellman_ford(int u)
{
memset(dist, 0x3f3f3f3f, sizeof(dist));
dist[u] = 0;
for (int i = 1; i < n; i++)
{
bool flag = false;
for (int j = 1; j <= m; j++)
{
if (dist[edge[j].v] > dist[edge[j].u] + edge[j].weight)
{
dist[edge[j].v] = dist[edge[j].u] + edge[j].weight;
flag = true;
}
}
if (!flag)
{
return false;
}
}
for (int j = 1; j <= m; j++)
{
if (dist[edge[j].v] > dist[edge[j].u] + edge[j].weight)
{
return true;
}
}
return false;
}
int main()
{
CreateGraph();
if (Bellman_ford(1))
{
cout << "图中有负环" << endl;
}
else
{
cout << "图中没有发现负环" << endl;
}
return 0;
}