HDU - 1384 Intervals (差分约束 spfa最长路)

You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.

Write a program that:

> reads the number of intervals, their endpoints and integers c1, ..., cn from the standard input,

> computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i = 1, 2, ..., n,

> writes the answer to the standard output

Input

The first line of the input contains an integer n (1 <= n <= 50 000) - the number of intervals. The following n lines describe the intervals. The i+1-th line of the input contains three integers ai, bi and ci separated by single spaces and such that 0 <= ai <= bi <= 50 000 and 1 <= ci <= bi - ai + 1.

Process to the end of file.
 

Output

The output contains exactly one integer equal to the minimal size of set Z sharing at least ci elements with interval [ai, bi], for each i = 1, 2, ..., n.

Sample Input

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

Sample Output

6

题意:

给定n个区间,每个区间内至少选中c个点,问整个数轴上至少选中多少个点

思路:

前几个月学的,比赛的时候竟然没有看出来qwq 枯了

当时写的博客https://blog.csdn.net/weixin_43871207/article/details/102484592

差分约束典型例题

设[0,i]共选中了d[i]个点,可以得出d[b] - d[a - 1] >= c,对于每个不等式建立一条从a - 1到b,权值为ci的边。

注意隐含条件:每个点至少选0次(即不选),至多选1次,所以除了对输入的多个区间建边外,还有d[i] - d[i - 1] >= 0 和d[i] - d[i  -1] <= 1,将第二个不等式转化为上面的形式即d[i - 1] - d[i] >= -1

防止数组越界,将所有数+1

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
typedef long long ll;
const int inf = 0xc0c0c0c0;
const int N = 5e4 + 20;

int tot, n, r;
int dis[N], vis[N], head[N], num[N];

struct Edge
{
    int u, v, w, next;
}edge[10 * N];

void add(int a, int b, int c)
{
    edge[tot].u = a;
    edge[tot].v = b;
    edge[tot].w = c;
    edge[tot].next = head[a];
    head[a] = tot++;
}

bool spfa(int s)
{
    queue<int>q;
    for(int i = 0; i <= r + 2; ++i)
        dis[i] = inf;
    memset(vis, 0, sizeof(vis));
    memset(num, 0, sizeof(num));
    q.push(s);
    dis[s] = 0;
    while(!q.empty())
    {
        int pos = q.front();
        q.pop();
        vis[pos] = 0;
        num[pos]++;
        for(int i = head[pos]; i != -1; i = edge[i].next)
        {
            if(dis[edge[i].v] < dis[edge[i].u] + edge[i].w)
            {
                dis[edge[i].v] = dis[edge[i].u] + edge[i].w;
                if(!vis[edge[i].v])
                {
                    vis[edge[i].v] = 1;
                    q.push(edge[i].v);
                    if(num[edge[i].v] >= r)
                        return 0;
                }
            }
        }
    }
    return 1;
}
int main()
{
    int a, b, c;
    while(~scanf("%d", &n))
    {
        tot = 0;
        memset(edge, 0, sizeof(edge));
        memset(head, -1, sizeof(head));
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d%d%d", &a, &b, &c);
            r = max(b, r);    ///最大值
            add(a, b + 1, c);
        }
        for(int i = 2; i <= r + 1; ++i)
        {
            add(i - 1, i, 0);
            add(i, i - 1, -1);
        }
        bool flag = spfa(1);    ///是否有正环(在本题中并不重要)
        if(flag && dis[r + 1] == inf)
            flag = 0;
        if(flag)
        {
            cout<<dis[r + 1]<<'\n';
        }
    }
    return 0;
}

 

全部评论

相关推荐

2025-12-12 19:58
哔哩哔哩_产品运营
跟同事聊天时候,同事说“你刚来时候blabla”,突然意识到自己已经正式工作一年多了!就这么从脆皮内耗大学生逐渐磨练成厚血条(厚脸皮)工位主理人。秋招简历当然也是投了不少份,但总有一些机会要留给自己的白月光,比如阿B,说说我秋招选择阿B的理由吧:1.&nbsp;“为爱发电”:说来兴趣真的是初心,阿B在手机陪我看了那么多番剧vlog学习视频,当然想和它距离更近一些。来了之后发现,B站重要活动要专门走内宣是有原因的,身边的六级大佬绝对不在少数。2.&nbsp;实习体验感拉满:嗯对其实等不到正式工作就先来实习体验了。实习期在一个非常好的组,大家都很年轻氛围超好,做事情讲背景、讲逻辑不会只丢脏活累活。平时聊得来,工作起来也能快速打配合,项目完成时候所有人都成就感满满。再说说来正式工作之后的体验感:1.&nbsp;校招生mentor文化很需要:在阿B每个校招生入职都是会有一位mentor的,不会让大家有刚工作人生地不熟就孤苦一人挑大梁的感觉。很幸运我的mt人真的超好,耐心温柔业务能力又很强。常常在对需求听她帮我说话时看着她身上闪耀的光芒想要流泪。有mt的话landing期会顺畅很多。公司也会安排一些活动帮助mentor和mentee增进感情。2.小动物们和各类活动是回血剂:工作起来当然难免遇到一些磕磕磨磨,但是压力大时候转头看到想悄悄溜过的小猫摸上一把,真的会治愈不少。还有节假日的各种活动和扫楼活动,真的会给上班增加动力。最后上图!没有任何工作会让人一直开心吧,但阿B你在照顾员工心情这一块儿做得真的很不错。
哔哩哔哩公司福利 904人发布
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务