[图论]【模板】差分约束算法(与Bellman-Ford算法)

P5960 【模板】差分约束算法

一, 描述

差分约束算法即对一组不等式求解,如上题.有ai-aj<k可以转化为ai<k+aj.

        我们突然发现这是一个最短路的形式 -- 具体来说, ai​≤aj​+k,根据上述分析,我们可以将其转化为从 j 到 i 的一条长度为 k的边,那么 ai​ 就转化成了源点到 i 的最短路径距离。如果题目无解就相当于有负环存在.

        但需要注意的是这个图可能是不连通的,即从一个点出发有些点一定无法到达.此时对于SPFA算法来说直接使用是不可以的,需要构建一个超级源点0,该点将连接所有点,并且距离为0.以该点为源点放入队列中.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 5e3 + 10, inf = 1e9;
int dis[maxn];
int n, m;

struct edge {//直接存边法
    int u, v, w;
}edge[maxn];

bool BFord()
{
    for (int i = 1; i <= n; i++) {
        dis[i] = inf;//初始化所有点到源点的距离
    }
    dis[1] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            dis[edge[j].v] = min(dis[edge[j].u] + edge[j].w, dis[edge[j].v]);//将所有点都松弛一遍,重复点的个数次
        }
    }
    for (int j = 1; j <= m; j++) {//将所有边遍历一次,如果有边还可以松弛则表示有负环,无解
        if (dis[edge[j].u] + edge[j].w < dis[edge[j].v])return false;//
    }
    return true;
}


int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) cin >> edge[i].v >> edge[i].u >> edge[i].w;
    if (BFord())
    {
        for (int i = 1; i <= n; i++) printf("%d ", dis[i]);
    }
    else printf("NO\n");
    return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值