Bellman-Ford最短路算法

381 阅读1分钟

Bellman-Ford算法

Bellman-Ford算法用来解决单源最短路问题:给定一个起点s,求他到图中所有n个节点的最短距离。

Bellman-Ford算法思想

基本思想和Floyd的思想很像,用起点s到i的距离可以分两种情况:分为路过k和路过k。取最小值就可以。

代码

int dist[N];//最多N个结点。dist:从起点到各个结点之间的距离 
int INF=0x3f;
struct edge{
	int u,v,w;
}e[M];//最多M条边
int n,m;//n个点,m条边
int begin;//起点 
int pre[N];//用于记录当前结点的前驱结点 
void BellmanFord()
{
	 for(int i=1;i<=n;i++) dist[i]=INF;//初始化初始距离为无限大
	 dist[begin]=0;//起点到起点的距离为0;
	 for(int k=0;k<n;k++)//一共检查n轮。k有一个含义,当前起点到每个点的最小值,最多有k条边参与。 
	 {
	 	for(int i=0;i<m;i++)
	 	{
	 		int u=e[i].u,v=e[i].v,w=e[i].w; 
	 		if(dist[v]>dist[u]+w)//起点到v的距离如果经过u更小,则经过u在到v; 
	 		{
	 			dist[v]=dist[u]+w;//更新距离 
	 			pre[v]=u; 
			 }
		 }
	  } 
} 
void print_path(int u,int v) //打印以u为起点,v为终点的最短路径 
{
	if(u==v) {cout<<u;return;}
	print_path(u,pre[v]);
	cout<<v;
}

判断负环

当图中没有负环时,只需n轮就可以结束。如果超过n轮说明有负环。

代码

bool BellmanFord()
{
	 for(int i=1;i<=n;i++) dist[i]=INF;//初始化初始距离为无限大
	 dist[begin]=0;//起点到起点的距离为0;
	 int k=0;
	 bool update=true; 
	 while(update)//一共检查n轮。k有一个含义,当前起点到每个点的最小值,最多有k条边参与。 
	 {
	 	k++;
	 	update=false;
	 	if(k>n) return true;//表示有负环 
	 	for(int i=0;i<m;i++)
	 	{
	 		int u=e[i].u,v=e[i].v,w=e[i].w; 
	 		if(dist[v]>dist[u]+w)//起点到v的距离如果经过u更小,则经过u在到v; 
	 		{
	 			update=true//如果本轮有更新,继续下一轮更新 
	 			dist[v]=dist[u]+w;//更新距离 
	 			pre[v]=u; 
			 }
		 }
		 return false;//不存在负环 
	  } 
}