Bellman-Ford 算法详解

/********************************************************************
 ** @file    my.cpp
 ** @date    Thu Apr 28 20:55:30 2011
 ** @brief   Bellman-ford 算法详解
 **    以poj2387 做试验
 **     
 ********************************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define MAX 4000
#define INF 1e9
struct node{
  int v,w,next;//next ->
}e[MAX];//next为下一条边的编号
int p[MAX];int t,n;
void init() {
  cin>>t>>n;
  memset(p,-1,sizeof(p));
  int a,b,w;int index=0;
  for(int i=0;i<t;++i){
    scanf("%d%d%d",&a,&b,&w);
    a--;b--;
    e[index].v=b;
    e[index].next=p[a];
    e[index].w=w;
    p[a]=index++;
    e[index].v=a;
    e[index].next=p[b];
    e[index].w=w;
    p[b]=index++;
  }
}
int Bellman_Ford(){
  int d[MAX];int num[MAX]={0};
  bool inQueue[MAX]={false};
  for(int i=0;i<n;++i)d[i]=(i==0?0:INF);
  queue<int>q;
  q.push(0);
  while(!q.empty()){
    int x=q.front();q.pop();
    inQueue[x]=false;/*清除在队列中的标志*/
    for(int j=p[x];j!=-1;j=e[j].next)
      if(d[e[j].v]>d[x]+e[j].w){
        d[e[j].v]=d[x]+e[j].w;
        if(!inQueue[e[j].v]){/*如果已经在队列中就不要重复加了*/
          inQueue[e[j].v]=true;q.push(e[j].v);
          num[e[j].v]++;/*记录每个点进队列的次数*/
          if(num[e[j].v]>n)return -1;//如果超过了n次说明有负环
        }
      }
  }
  return d[n-1];
}
/* 思考Bellman-Ford算法,它是如何结束的?显然,最朴素的Bellman-Ford算法不管循环过程中
   发生了什么,一概要循环|V|-1遍才肯结束。凭直觉我们可以感到,SPFA算法“更聪明一些”,
   就是说我们可以猜测,假如在SPFA中,一个点进入队列——或者说一个点被处理——超过了|V|次,
   那么就可以断定图中存在负权回路了。
*/
int main(int argc, char *argv[])
{
  init();
  int d=Bellman_Ford();
  if(d!=-1)
  printf("%d/n",d);
  return 0;
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/zhuyingqingfen/article/details/6370617
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞