差分约束系统 + spfa求最短路

首先先来个具体的题目来引入一下。

Intervals(UVA1723)

题面翻译

n n n 个区间,在区间 [ a i , b i ] [a_i,b_i] [ai,bi] 中至少取任意互不相同的 c i c_i ci 个整数。求在满足 n n n 个区间的情况下,至少要取多少个正整数。

输入格式

本题有多组数据

第一行的一个整数 T T T 表示数据个数,后面有一行空行。

对于每组数据:

第一行包含一个整数 n ( 1 ≤ n ≤ 50000 ) n(1\leq n\leq 50000) n(1n50000) 表示区间数。

以下 n n n 行描述区间。

输入的第 i + 1 i+1 i+1 行包含三个整数 a i , b i , c i a_i,b_i,c_i ai,bi,ci,由空格分开。其中 0 ≤ a i ≤ b i ≤ 50000 , 1 ≤ c i ≤ b i − a i + 1 0\leq a_i\leq b_i\leq 50000,1\leq c_i\leq b_i-a_i+1 0aibi500001cibiai+1

输出格式

对于每组数据,输出一个对于 n n n 个区间 [ a i , b i ] [a_i,b_i] [ai,bi]
至少取 c i c_i ci 个不同整数的数的总个数。

在除了最后一组数据后输出空行。

样例

input:

1

5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1

output:

6

样例解释

可以取 3 , 4 , 5 , 8 , 9 , 10 3,4,5,8,9,10 3,4,5,8,9,10,为符合条件且取数个数最少的一组解。

题目模型的转换

我们建立一个新的数组, d [ i ] d[i] d[i] 表示 [ 0 , i − 1 ] [0, i - 1] [0,i1] 这个区间内一共被选中了多少个数字,我们用题目中给出来的样例来举例子。

5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1

通过上面的这些数据,我们就能知道 d [ i ] d[i] d[i] 需要满足以下这些条件。

{ d [ 8 ] − d [ 3 ] ≥ 3 d [ 11 ] − d [ 8 ] ≥ 3 d [ 9 ] − d [ 6 ] ≥ 1 d [ 4 ] − d [ 1 ] ≥ 1 d [ 12 ] − d [ 10 ] ≥ 1 \left\{\begin{aligned} d[8] - d[3] \ge 3 \\ d[11]-d[8] \ge 3 \\ d[9] - d[6] \ge 1 \\ d[4] - d[1] \ge 1 \\ d[12] - d[10] \ge 1 \end{aligned}\right. d[8]d[3]3d[11]d[8]3d[9]d[6]1d[4]d[1]1d[12]d[10]1

然后我们再重新整理一下上面的这些不等式。

{ d [ 8 ] ≥ d [ 3 ] + 3 d [ 11 ] ≥ d [ 8 ] + 3 d [ 9 ] ≥ d [ 6 ] + 1 d [ 4 ] ≥ d [ 1 ] + 1 d [ 12 ] ≥ d [ 10 ] + 1 \left\{\begin{aligned} d[8] \ge d[3] + 3 \\ d[11] \ge d[8] + 3 \\ d[9] \ge d[6] + 1 \\ d[4] \ge d[1] + 1 \\ d[12] \ge d[10] + 1 \end{aligned}\right. d[8]d[3]+3d[11]d[8]+3d[9]d[6]+1d[4]d[1]+1d[12]d[10]+1

除此之外,我们需要注意,因为 d 数组是一个前缀和,所以我们也需要维护好前缀和的合法性,也就是: ∀ i > 0 , d [ i ] ≥ d [ i − 1 ] , d [ i − 1 ] ≥ d [ i ] − 1 \forall i>0,d[i] \ge d[i - 1],d[i - 1]\ge d[i] - 1 i>0,d[i]d[i1],d[i1]d[i]1,这两个式子使得两个相邻的 d 元素,满足前缀和的要求,后面的要么等于前面的,要么比前面的大一。

那么我们只需要使得 d 数组 恰好 满足上面的种种条件,或者说使得 d 数组 恰好 满足上面的种种约束,我们就可以求出此题的答案(例如样例中 d[12] 就是最终结果,因为被选中的数字肯定小于 12)。

用 spfa 求出满足所有约束的 d 数组

我们先来看一下 spfa 的代码。

int spfa()
{
    memset(d, -0x3f3f3f3f, sizeof(d));
    memset(vis, 0, sizeof(vis));
    d[0] = 0, vis[0] = 1;
    queue<int> q;
    q.push(0);
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for (int i = 0; i < e[u].size(); i++)
        {
            int v = e[u][i].first;
            int w = e[u][i].second;
            if (d[v] < d[u] + w) // 注意这里
            {
                d[v] = d[u] + w;
                if (!vis[v])
                {
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
    for (int i = 0; i <= 50000; i++)
        e[i].clear();
    return d[t];
}

这是一个 spfa 的代码,我们注意代码中出现注释的部分,spfa 会不停的寻找满足这个条件的边,找到了之后呢?我们就会修改 d[v] 的值,使得 d [ v ] ≥ d [ u ] + w d[v] \ge d[u] + w d[v]d[u]+w (大家有没有觉得这个式子特别的熟悉?),直到所有的边全部都恰好满足条件为止,那么我们为什么不能用上面 d 数组中元素两两之间的关系来代替边权呢?

所以此题就有了以下的这个代码。

#include <bits/stdc++.h>
#define mp(a, b) make_pair(a, b)

using namespace std;

const int maxn = 50005;
int dis[maxn], vis[maxn], n, t;

vector<pair<int, int>> e[maxn];

int spfa() // 正常的一个最长路的代码,注意初始化
{
    memset(dis, -0x3f3f3f3f, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    dis[0] = 0, vis[0] = 1;
    queue<int> q;
    q.push(0);
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for (int i = 0; i < e[u].size(); i++)
        {
            int v = e[u][i].first;
            int w = e[u][i].second;
            if (dis[v] < dis[u] + w)
            {
                dis[v] = dis[u] + w;
                if (!vis[v])
                {
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
    for (int i = 0; i <= 50000; i++)
        e[i].clear();
    return dis[t];
}

int solve()
{
    cin >> n;
    t = 0;
    for (int i = 1; i <= n; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        e[a].push_back(mp(b + 1, c)); // 题目中给出的约束
        t = max(t, b + 1);            // t 是图中最大的点,所有被选中的数字全部都小于 t
    }
    for (int i = 1; i <= t; i++)
    {
        e[i - 1].push_back(mp(i, 0)); // 为了使得前缀和合法而添加的约束
        e[i].push_back(mp(i - 1, -1));
    }
    int ans = spfa();
    return ans;
}

int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        cout << solve() << '\n';
        if (T) // 输出格式有要求,大家要注意
            cout << '\n';
    }
    return 0;
}









本人能力有限,如有不当之处敬请指教!祝大家新年快乐!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/961921.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安卓(android)实现注册界面【Android移动开发基础案例教程(第2版)黑马程序员】

一、实验目的&#xff08;如果代码有错漏&#xff0c;可查看源码&#xff09; 1.掌握LinearLayout、RelativeLayout、FrameLayout等布局的综合使用。 2.掌握ImageView、TextView、EditText、CheckBox、Button、RadioGroup、RadioButton、ListView、RecyclerView等控件在项目中的…

Prompt提示词完整案例:让chatGPT成为“书单推荐”的高手

大家好&#xff0c;我是老六哥&#xff0c;我正在共享使用AI提高工作效率的技巧。欢迎关注我&#xff0c;共同提高使用AI的技能&#xff0c;让AI成功你的个人助理。 许多人可能会跟老六哥一样&#xff0c;有过这样的体验&#xff1a;当我们遇到一个能力出众或对事物有独到见解的…

智慧园区管理平台实现智能整合提升企业运营模式与管理效率

内容概要 在当今数字化的背景下&#xff0c;智慧园区管理平台正逐渐成为企业提升运营效率和管理模式的重要工具。这个平台汇聚了多种先进技术&#xff0c;旨在通过智能整合各类资源与信息&#xff0c;帮助企业实现全面的管理创新。 智慧园区管理平台不仅仅是一个数据处理工具…

Baklib如何提升企业知识管理效率与市场竞争力的五大对比分析

内容概要 在信息化时代&#xff0c;企业在知识管理方面面临着巨大的挑战与机遇。为了有效应对这些挑战&#xff0c;“Baklib”作为一个知识中台&#xff0c;通过其高度集成的数字化平台&#xff0c;为企业提供全方位的知识管理解决方案。特别是在以下五个领域&#xff0c;它展…

c++:vector

1.使用 1.1构造函数 常见的三种构造方式&#xff1a;空构造&#xff0c;拷贝构造&#xff0c;指定元素构造 1.2iterator begin和end也分为正向和反向。 注意&#xff1a;反向迭代器可以反向遍历是因为在定义rbegin和rend函数的时候把尾地址给到了rbegin&#xff0c;而不是说改…

C++17 搜索器教程:解锁高效搜索新姿势

C17搜索器教程&#xff1a;解锁高效搜索新姿势 C17搜索器简介 在C的发展历程中&#xff0c;C17是一个重要的里程碑&#xff0c;它引入了诸多实用的新特性&#xff0c;搜索器功能便是其中之一。此功能着重对std::search算法进行了强化&#xff0c;使其支持多种搜索策略&#x…

Transformer+vit原理分析

目录 一、Transformer的核心思想 1. 自注意力机制&#xff08;Self-Attention&#xff09; 2. 多头注意力&#xff08;Multi-Head Attention&#xff09; 二、Transformer的架构 1. 整体结构 2. 编码器层&#xff08;Encoder Layer&#xff09; 3. 解码器层&#xff08;Decoder…

C语言自定义数据类型详解(二)——结构体类型(下)

书接上回&#xff0c;前面我们已经给大家介绍了如何去声明和创建一个结构体&#xff0c;如何初始化结构体变量等这些关于结构体的基础知识。下面我们将继续给大家介绍和结构体有关的知识&#xff1a; 今天的主题是&#xff1a;结构体大小的计算并简单了解一下位段的相关知识。…

【ComfyUI专栏】如何使用Git命令行安装非Manager收录节点

当前的ComfyUI的收录的自定义节点很多&#xff0c;但是有些节点属于新出来&#xff0c;或者他的应用没有那么广泛&#xff0c;Manager管理节点 有可能没有收录到&#xff0c;这时候 如果我们需要安装需要怎么办呢&#xff1f;这就涉及到我们自己安装这些节点了。例如下面的内容…

【Block总结】PKI 模块,无膨胀多尺度卷积,增强特征提取的能力|即插即用

论文信息 标题: Poly Kernel Inception Network for Remote Sensing Detection 作者: Xinhao Cai, Qiuxia Lai, Yuwei Wang, Wenguan Wang, Zeren Sun, Yazhou Yao 论文链接&#xff1a;https://arxiv.org/pdf/2403.06258 代码链接&#xff1a;https://github.com/NUST-Mac…

[OO ALV] OO ALV 基础显示

程序代码 REPORT z437_test_2025.DATA gt_spfli TYPE STANDARD TABLE OF spfli. " 内表DATA go_alv TYPE REF TO cl_gui_alv_grid. " 创建和管理ALV表格DATA gs_layout TYPE lvc_s_layo. " 存储ALV表格的布局信息*---------------------…

jQuery小游戏(二)

jQuery小游戏&#xff08;二&#xff09; 今天是新年的第二天&#xff0c;本人在这里祝大家&#xff0c;新年快乐&#xff0c;万事胜意&#x1f495; 紧接jQuery小游戏&#xff08;一&#xff09;的内容&#xff0c;我们开始继续往下咯&#x1f61c; 游戏中使用到的方法 key…

Linux的常用指令的用法

目录 Linux下基本指令 whoami ls指令&#xff1a; 文件&#xff1a; touch clear pwd cd mkdir rmdir指令 && rm 指令 man指令 cp mv cat more less head tail 管道和重定向 1. 重定向&#xff08;Redirection&#xff09; 2. 管道&#xff08;Pipes&a…

蓝桥杯之c++入门(一)【C++入门】

目录 前言5. 算术操作符5.1 算术操作符5.2 浮点数的除法5.3 负数取模5.4 数值溢出5.5 练习练习1&#xff1a;计算 ( a b ) ⋆ c (ab)^{\star}c (ab)⋆c练习2&#xff1a;带余除法练习3&#xff1a;整数个位练习4&#xff1a;整数十位练习5&#xff1a;时间转换练习6&#xff…

51单片机开发:定时器中断

目标&#xff1a;利用定时器中断&#xff0c;每隔1s开启/熄灭LED1灯。 外部中断结构图如下图所示&#xff0c;要使用定时器中断T0&#xff0c;须开启TE0、ET0。&#xff1a; 系统中断号如下图所示&#xff1a;定时器0的中断号为1。 定时器0的工作方式1原理图如下图所示&#x…

【设计测试用例自动化测试性能测试 实战篇】

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a; c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 设计测试用例…

指针(C语言)从0到1掌握指针,为后续学习c++打下基础

目录 一&#xff0c;指针 二&#xff0c;内存地址和指针 1&#xff0c;什么是内存地址 2&#xff0c;指针在不同系统下所占内存 三&#xff0c;指针的声明和初始化以及类型 1,指针的声明 2,指针 的初始化 1&#xff0c; 初始化方式优点及适用场景 4,指针的声明初始化类型…

利用Redis实现数据缓存

目录 1 为啥要缓存捏&#xff1f; 2 基本流程&#xff08;以查询商铺信息为例&#xff09; 3 实现数据库与缓存双写一致 3.1 内存淘汰 3.2 超时剔除&#xff08;半自动&#xff09; 3.3 主动更新&#xff08;手动&#xff09; 3.3.1 双写方案 3.3.2 读写穿透方案 3.3.…

MySQL(高级特性篇) 14 章——MySQL事务日志

事务有4种特性&#xff1a;原子性、一致性、隔离性和持久性 事务的隔离性由锁机制实现事务的原子性、一致性和持久性由事务的redo日志和undo日志来保证&#xff08;1&#xff09;REDO LOG称为重做日志&#xff0c;用来保证事务的持久性&#xff08;2&#xff09;UNDO LOG称为回…

S4 HANA明确税金本币和外币之间转换汇率确定(OBC8)

本文主要介绍在S4 HANA OP中明确明确税金本币和外币之间转换汇率确定(OBC8)相关设置。具体请参照如下内容&#xff1a; 明确税金本币和外币之间转换汇率确定(OBC8) 以上配置&#xff0c;我们可以根据不同公司代码所配置的使用不同的汇率来对税金外币和本币之间进行换算。来针对…