关闭

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

220人阅读 评论(0) 收藏 举报
分类:
//含有负权边的单源点最短路径
//动态规划思想:两点之间的最短路径最多经过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
*/

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:22069次
    • 积分:900
    • 等级:
    • 排名:千里之外
    • 原创:68篇
    • 转载:5篇
    • 译文:0篇
    • 评论:1条
    最新评论