ACM模板 Bellman_Ford,单源最短路,图论

dijkstra算法只能处理不带有负权边的图的单源最短的路问题,而Bellman_Ford算法则更一般,不仅能够处理带有负权边的图,而且能够在图中存在负权回路的时候返回出错信息。

/*===========================================================*\
 * Bellman_Ford                    2014.7.19_basement_boy
 * 单源最短路,有向图无向图,边权可正可负(存在负权回路的话返回false)
 * INIT:初始化边集edge[],无向边当作两条有向边处理
 * 函数调用后,
 * 返回值如果是true,说明不存在负权回路
 * pre[]表示从源点到各个点路径的路径树
 * dist[]表示从源点到各个点的最短路长度
\*===========================================================*/

struct Edge{ //边类型定义
	int u,v; //起点和终点
	int l;   //边长-----------------------------******(可能是浮点型)
};
int n,m;   //n是点数,m是边数
const int N=550,M=5500; //问题中给出的可能的最大点数和最大边数(无向边算两条边)-----------------*******(根据实际问题修改)
const int MAXL = 0x3f3f3f3f;   //边的无限长
Edge edge[M+10];  //边集
int pre[N+10];    //从源点到该点的路径上该点的前驱(以源点为根的路径树,根结点的值为-1)
int dist[N+10];   //从源点到该点的最短距离

//松弛操作
bool relax( Edge e ){
	if( dist[e.v] > dist[e.u]+e.l ){
		dist[e.v] = dist[e.u]+e.l;
		pre[e.v] = e.u;
		return true;  //进行更新的话返回真值
	}
	return false;
}
bool bellman(int s){
    //初始化dist[] 和 pre[]
	for(int i=0 ; i<n ; i++){
		dist[i] = MAXL;
		pre[i] = -1;
	}
	dist[s] = 0;
	
	bool change = false;  //使用标记优化,提高效率
	for(int i=1 ; i<n ; i++){
		change = false;
		for(int j=0 ; j<m ; j++){
		    if( relax(edge[j]) )
              change = relax;
        }
		if( !change ) //如果对所有边进行的一次relax()操作没有更新说明已经找到了到所有点的最短路
		  break;
	}
	
    for(int i=0 ; i<m ; i++){
		if( relax(edge[i]) )
			return false; //再对所有边进行一次relax()操作,如果有更新dist[]则说明存在负权回路
	}
	return true;
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/u012278856/article/details/37961983
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞