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

来源:互联网 发布:教授知乎 编辑:程序博客网 时间:2024/05/21 12:39
//含有负权边的单源点最短路径//动态规划思想:两点之间的最短路径最多经过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 52 3 21 2 -31 5 54 5 23 4 3*/

0 0