您的位置:首页 > 其它

Bellman-Ford算法模板

2016-04-13 20:55 459 查看
Bellman-Ford算法最重要的一个应用是判负环。

在迭代n-1次后如果还可以进行松弛操作,说明一定存在负圈。

如果包含负环,则路径不存在。

以下为SPFA优化模板:

#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<cstdlib>
#define inf 0x3f3f3f3f
#define LL long long
using namespace std;
struct Edge
{
int from,to,dist;
};
vector<Edge> edges;
vector<int> g[1005];//存储from对应的边的标号
bool inq[1005];//是否在队列中
int d[1005];//源点到各个点的最短路
int pre[1005];//最短路的上一条弧
int cnt[1005];//进队次数
int n,m;//n点的个数,m边的个数
int a,b;//求a到b的最短路径并输出a到b的路径
void init()
{
for(int i=0;i<=n-1;i++)
g[i].clear();
edges.clear();
}
void addedge(int from,int to,int dist)//边从0开始
{
edges.push_back((Edge){from,to,dist});
int num=edges.size();
g[from].push_back(num-1);
}
bool spfa(int s)//若存在负环返回false
{
queue<int> q;
memset(inq,0,sizeof(inq));
memset(cnt,0,sizeof(cnt));
memset(d,0x3f,sizeof(d));
d[s]=0;
inq[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
inq[u]=0;
for(int i=0;i<g[u].size();i++)
{
Edge e=edges[g[u][i]];
if(d[e.to]>d[u]+e.dist)
{
d[e.to]=d[u]+e.dist;
pre[e.to]=g[u][i];
if(!inq[e.to])
{
q.push(e.to);
inq[e.to]=1;
if(++cnt[e.to]>n)
return false;//有负环
}
}
}
}
return true;
}
void print(int s)//输出源点a到s的最短路径
{
if(s==a)
return ;
print(edges[pre[s]].from);
cout<<edges[pre[s]].from<<" ";
}
int main()
{
cin>>n>>m;
init();
for(int i=0;i<=m-1;i++)
{
int a,b,c;
cin>>a>>b>>c;
addedge(a,b,c);
}
cin>>a>>b;//求a到b最短路
if(spfa(a))
{
cout<<d[b]<<endl;
print(b);
cout<<b<<endl;
}
else
cout<<-1<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: