/********************************************************************
** @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 算法详解
原文作者:Bellman - ford算法
原文地址: https://blog.csdn.net/zhuyingqingfen/article/details/6370617
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/zhuyingqingfen/article/details/6370617
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。