ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

图论——Bellman-Ford算法

2022-07-18 13:35:42  阅读:157  来源: 互联网

标签:图论 int Bellman Ford 枚举 edge dis


这篇里,我们讲到,对于有负权值的情况下,一般用Bellman_Ford。

今天就来详述一下Bellman_Ford与其例题。

Bellman_Ford的思想非常简单,首先第一层枚举点,第二层枚举每一条边。

与其说第一层是枚举,其实不如说它是单纯循环,因为,有些题目中,第一层就是单纯循环,对于需要枚举节点的题目来说,它还是一样的写法。

第二层循环有3个变量:a,b,w,a表示边的起点,b表示边的终点,w表示边的权值,Bellman_Ford的存边方式很灵活,只要保证能遍历到每条边的起点、终点、权值就可以了,不一定非得用邻接表或邻接矩阵。我们可以开一个结构体,里面放3个变量:a,b,w;一个结构体数组edge[]既然都用了edge,所以这就是存边用的。

而它循环内执行的操作和Dijkstra十分相像。dis[edge[j].b]=min(dis[edge[j].b],bc[edge[j].a]+edge[j].w);就可以。再看一个例题:

  求出从1号点到n号点的最多经过k条边的最短距离,如果无法从1号点走到n号点,输出impossible

这道题只能用Bellman_Ford做,其他均不可以(包括SPFA),在这一题中,第一层循环中,我们枚举的就是k因为只要枚举次数小于k次,就1一定能保证经过的边数小于k。

最后再判断,如果求出的答案是初始值,那么输出不可能就行。

代码: 

#include<bits/stdc++.h>
using namespace std;
int n,m,dis[505],bc[505],aa,bb,ww,k;
struct aaa{
    int a,b,w;
}edge[10005];
int main(){
    memset(dis,0x3f,sizeof dis);
    dis[1]=0;
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++){
        cin>>aa>>bb>>ww;
        edge[i]={aa,bb,ww};
    }
    for(int i=1;i<=k;i++){
        memcpy(bc,dis,sizeof dis);
        for(int j=1;j<=m;j++)                         
            dis[edge[j].b]=min(dis[edge[j].b],bc[edge[j].a]+edge[j].w);
    }
    if(dis[n]>0x3f3f3f3f/2) cout<<"impossible";
    else cout<<dis[n];
    return 0;
} 

  

标签:图论,int,Bellman,Ford,枚举,edge,dis
来源: https://www.cnblogs.com/jnlc-yab0716/p/16490078.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有