//Bellman_Ford算法(可判断有无权为负的回路)
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <map>
#define maxn 1005
#define inf 0x3f3f3f3f
using namespace std;
map<int, int>mp;
int dist[maxn];
int pre[maxn];
struct Edge
{
int u, v, cost;
}edge[maxn];
int Bellman_Ford(int nodenum, int edgenum, int orig)
{
for(int i=1; i<=nodenum; i++)
dist[i] = i==orig?0:inf;
pre[orig] = orig;
for(int i=1; i<nodenum; i++)
for(int j=1; j<=edgenum; j++)
{
if(dist[edge[j].v]>dist[edge[j].u] + edge[j].cost)
{
dist[edge[j].v] = dist[edge[j].u] + edge[j].cost;
pre[edge[j].v] = edge[j].u;
}
}
int res = 1;
for(int j=1; j<=edgenum; j++)
{
if(dist[edge[j].v]>dist[edge[j].u] + edge[j].cost)
{
res = 0;
break;
}
}
return res;
}
//反向输出路径
void f_path(int root)
{
while(root!=pre[root])
{
printf("%d, ", root);
root = pre[root];
}
if(root==pre[root])
printf(", %d", root);
}
//正向输出路径
void z_path(int root)
{
int path[maxn];
int k = 0;
while(root!=pre[root])
{
path[k++] = root;
root = pre[root];
}
path[k++] = root;
for(int i=0; i<k; i++)
printf("%d, ",path[k-i-1]);
printf("\n\n");
}
int main()
{
int nodenum, edgenum, orig;
while(scanf("%d%d%d", &nodenum, &edgenum, &orig)!=EOF)
{
//无向图,可重边,点u->v的权值存在mp[u*maxn+v]中, 结构体edge中的cost可去掉
/*mp.clear();
int k=0;
for(int i=1; i<=edgenum; i++)
{
int u, v, cost;
scanf("%d%d%d", &u, &v, &cost);
if(mp[u*maxn+v])
{
mp[v*maxn+u] = mp[u*maxn+v] = min(mp[u*maxn + v], cost);
}
else
{
edge[k++].u = u;
edge[k-1].v = v;
edge[k++].u = v;
edge[k-1].v = u;
mp[v*maxn+u] = mp[u*maxn+v] = cost;
}
}
*/
//有向图,且没有重边
for(int i=1; i<=edgenum; i++)
scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].cost);
if(Bellman_Ford(nodenum, edgenum, orig))
{
for(int i=1; i<=nodenum; i++)
{
printf("%d->%d的最短路长度:%d\n", orig, i, dist[i]);
printf("反向路径是:");
f_path(i);
printf("\n正向路径是:");
z_path(i);
}
}
else
printf("存在负环\n");
}
return 0;
}
最短路径算法—Bellman-Ford模板
最新推荐文章于 2022-04-27 21:04:15 发布
本文详细介绍Bellman-Ford算法的实现原理及代码实现过程,该算法能够有效地解决带负权边的最短路径问题,并能检测是否存在负权回路。文章通过具体的代码示例解释了如何使用该算法进行最短路径计算及其路径反向和正向输出。
摘要由CSDN通过智能技术生成