您的位置:首页 > 其它

图的最短路径算法(四)--Bellman-Ford(解决负权边)单源点最短路径

2016-08-29 22:06 369 查看
//含有负权边的单源点最短路径
//动态规划思想:两点之间的最短路径最多经过n-1边即可到达
//那么依次更新经过1条边,2条边,...,n-1条边的最短路径

#include<stdio.h>
int main()
{
int dis[10],bak[10],i,k,n,m,u[10],v[10],w[10],check,flag;
int inf=99999999;
//读入n和m,n表示顶点个数,m表示边的条数
scanf("%d %d",&n,&m);

//读入边
for(i=1;i<=m;i++)
{
scanf("%d %d %d",&u[i],&v[i],&w[i]);
}

//初始化dis数组,这里是1号顶点到其余各顶点的初始路程
for(i=1;i<=n;i++)
dis[i]=inf;
dis[1]=0;

//Bellman-Ford算法核心语句
for(k=1;k<=n-1;k++)
{
//将dis数组备份到bak数组中
for(i=1;i<=n;i++)
bak[i]=dis[i];
//进行一轮松弛
for(i=1;i<=m;i++)
if(dis[v[i]]>dis[u[i]]+w[i])     //这里好像将图的边看成了有向边
dis[v[i]]=dis[u[i]]+w[i];
//松弛完毕后检测dis数组是否有更新
check=0;
for(i=1;i<=n;i++)
if(bak[i]!=dis[i])
{
check=1;
break;
}
if(check==0)
break;    //数组没有更新,提前退出循环算法
}
//检测负权回路
flag=0;
for(i=1;i<=m;i++)
if(dis[v[i]]>dis[u[i]]+w[i])
flag=1;
if(flag==1)
printf("此图含负权回路");
else
{
//输出最终结果
for(i=1;i<=n;i++)
printf("%d ",dis[i]);
}
return 0;
}

/*
5 5
2 3 2
1 2 -3
1 5 5
4 5 2
3 4 3
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐