【差分约束系统】间隔Intervals

【差分约束系统】间隔Intervals

并没有什么用的更新时间

【2019/07/10】 题目及代码(伪)、题解更新
【2021/05/16】 我人真的傻了 这已经超出碳基生物的整活范围了 没想到时隔多年重学差分约束系统 搜到的题解竟然是两年前自己打的555我真的是越学越菜 不过代码好像贴成楼下树形DP的了 更新了代码


间隔Intervals

tip:翻译来自谷歌,如有出入请见谅

  • 题目描述
    给定n个闭合的整数区间[ai,bi]和n个整数c1,…,cn。
    编写一个程序: 从标准输入读取间隔数,它们的终点和整数c1,…,cn, 计算整数集合Z的最小尺寸,它至少具有ci公共元素的间隔[ai, bi],对于每个i = 1,2,…,n, 将答案写入标准输出。
    You are given n closed, integer intervals [ai, bi] and n integers c1, …, cn.
    Write a program that: reads the number of intervals, their end points 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.
  • 输入输出格式
  • 输入格式:
    输入的第一行包含整数n(1 <= n <= 50000) - 间隔数。以下n行描述了间隔。输入的第(i + 1)行包含由单个空格分隔的三个整数ai,bi和ci,并且使得0 <= ai <= bi <= 50000并且1 <= ci <= bi-ai + 1。
    The first line of the input contains an integer n (1 <= n <= 50000) – 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 <= 50000 and 1 <= ci <= bi - ai+1.
  • 输出格式:
    对于每个i = 1,2,…,n,输出恰好包含一个等于集合Z的最小尺寸的整数,该集合Z至少与区间[ai,bi]共享ci元素。
    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.
  • 输入输出样例
  • 输入样例#1:
    5
    3 7 3
    8 10 3
    6 8 1
    1 3 1
    10 11 1
  • 输出样例#1:
    6
  • 题解
    题目难度:★★★☆☆
    思路:假设d[i] 是 [1,i] 至少有多少个点被选中, 特殊地, d[0] = 0。 每个区间的描述可以转化为d[R] - d[L-1] >= w。(因为d[L]也要选中, 左闭右闭区间, 所以要减d[L-1])
    因为d[i]描述了一个求和函数,所以对于d[i]和d[i-1]其实是有自身限制的,考虑到每个点有选和不选两种状态,所以d[i]和d[i-1]需要满足以下不等式: 0 <= d[i] - d[i-1] <= 1 (即第i个数选还是不选)
    这样, 我们就有了3个约束不等式
    d[R] - d[L-1] >= w  (1)
    d[i] - d[i-1] >= 0   (2)
    d[i-1] - d[i] >= -1 (3)
    求出d[min]到d[max]的最长路, d[max] 就是这个区间最少要放多少个球。
    差分约束系统
    对于每个不等式 x[i] - x[j] >= a[k],对结点 j 和 i 建立一条 j -> i的有向边,边权为a[k],求x[n] - x[1] 的最大值就是求 1 到n的最长路。
    假设d[i] 是 [1,i] 至少有多少个点被选中, 特殊地, d[0] = 0;
    每个区间的描述可以转化为d[R] - d[L-1] >= w
    因为d[i]描述了一个求和函数,所以对于d[i]和d[i-1]其实是有自身限制的,考虑到每个点有选和不选两种状态,
    所以d[i]和d[i-1]需要满足以下不等式: 0 <= d[i] - d[i-1] <= 1 (即第i个数选还是不选)
  • 代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=50005;
struct edge
{
 int v,w,next;
}e[maxn*3];
int head[maxn],dis[maxn],vis[maxn],cnt,n,u,v,w,st,fi;
void addedge(int u,int v,int w){
	e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void spfa(int s){
	queue<int> q;
	for (int i=st;i<=fi+1;++i){
		dis[i]=-INF;
		vis[i]=0;
	}
    dis[s]=0,vis[s]=1;
    q.push(s);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        for (int i=head[u];i;i=e[i].next){
            int v=e[i].v;
            if(dis[v]<dis[u]+e[i].w){
              dis[v]=dis[u]+e[i].w;
              if(!vis[v]){
                vis[v]=1;
                q.push(v);
              }
            }
        }
    }
  cout<<dis[fi+1]<<endl;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;++i){
		scanf("%d%d%d",&u,&v,&w);
		addedge(u,v+1,w);
		fi=max(fi,v);
		st=min(st,u);
	}
	for (int i=st;i<=fi+1;++i){
		addedge(i,i+1,0);
		addedge(i+1,i,-1);
    }
	spfa(st);
}
  • 相关连接

北大P1201

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值