差分约束 解决区间选点问题

2023-05-16

题意:

给定一个数轴上的 n 个区间,要求在数轴上选取最少的点使得第 i 个区间 [ai, bi] 里至少有 ci 个点。

input:

输入第一行一个整数 n 表示区间的个数,接下来的 n 行,每一行两个用空格隔开的整数 a,b 表示区间的左右端点。1 <= n <= 50000, 0 <= ai <= bi <= 50000 并且 1 <= ci <= bi - ai+1。

output:

输出一个整数表示最少选取的点的个数。

样例数据:
input:

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

output:

6

思路:

(小声说,如果是自己写题,肯定是无论如何也想不到这么高端的差分约束的做法。)用差分约束,主要就是思考如何构建差分约束的条件,即如何构建差分约束的图。将图构建完成后,利用spfa来根据题意,是跑最常路还是最短路,修改条件即可。
构建图:首先要构造不等式组。可以记sum[i](在此处用的dis),为数轴【0,i】之间需要选点的个数。
**对于第i个区间[ai,bi]之间需要满足,sum[bi]-sum[ai-1]>=ci,其中ci即为这个区间需要选点的个数,另外为了保证sum有意义,需要保证 0<=sum[i]-sum[i-1]<=1。**根据上述的条件即可构建图来。
如何构建图:
在这里插入图片描述
在这里插入图片描述
在此附上学长给的链接,跟着说明来构建图还是能理解的。

https://blog.csdn.net/kk303/article/details/6864199

即按照上述来选择起始点和终点以及边权,构建好图,在利用spfa即可得到所需要的解。注意跑最短路得到的是最大解,跑最长路得到的是最小的解。还要注意在这样构建时,由于左区间,即起始点有a-1的限制,故原先的起点0会多出来一个-1点,即增加一个点即可(如果这个点没有路,多出来的-1也并不影响,因为其到0的距离为0)。

代码:

#include <cstdio>
#include <algorithm> 
#include <iostream>
#include <string.h> 
#include <queue>
#include <cmath>
using namespace std;

int n;
int a, b,c;
int dis[50010];  //记录长度 

int vis[50010];  //是否在队列中
int cnt[50010];  //记录到达该点所经历的边数
 
struct Edge{
	int to, next, w;   //到哪点 下一条边 边的权值 
}e[200050];
int head[50010];
int tot;  //当前的边数

queue<int> q;


//     到哪点    去哪点     权值 
void add_edge(int t, int f, int w){
	e[tot].to=t;
	e[tot].next=head[f];
	head[f]=tot;
	e[tot].w=w;
	tot++;	
} 


queue <int> q2;
bool vis2[205]; 

void bfs(int x){
	while (q2.size()) q2.pop();
	
	memset(vis2,0,sizeof(vis2));
	dis[x]=-1;
	vis2[x] = 1;
	q2.push(x);
	while(q2.size()){
		int x = q2.front();
		q2.pop();
		
		int i = head[x];
		while (i != -1) {
			int t1 = e[i].to;
			if(vis2[t1]==0){
				q2.push(t1);
				vis2[t1]=1;
				dis[t1]=-1;
			}
			i = e[i].next;
		}
	}	
}



void spfa() {
	while (q.size()) q.pop();

	//初始化
	dis[0] = 0, vis[0]=1;
	q.push(0);
	while (q.size()) {
		int x = q.front();
		q.pop();
		vis[x] = 0;  //x出队列,标记值为0,在spfa中可以被队列弹出多次 
		
		int i = head[x];
		while (i != -1) {
			int t1 = e[i].to;
			int w1 = e[i].w;
			if (dis[t1] < dis[x] + w1) {
				dis[t1] = dis[x] + w1;  //记录路径长度 
				cnt[t1]=cnt[x]+1;
				if(cnt[t1]>=50000){
					bfs(t1);
				}else if(dis[t1]!=-1 && vis[t1]==0){
					q.push(t1);
					vis[t1]=1;
				}	
			}
			i = e[i].next;
		}
	}
}

int main(){
	scanf("%d",&n);
	tot=0;
	//初始化   0-50000  由于 a-1,故多出一个点 
	for(int i=0; i<=50001; i++){
		head[i]=-1;
		dis[i]=-10000;
		vis[i]=0;
		cnt[i]=0;		
	} 
	
	for(int i=0; i<50001; i++){ 
		add_edge(i+1,i,0);
		add_edge(i,i+1,-1);   	
	}
	
	for(int i=0; i<n; i++){
		scanf("%d%d%d",&a,&b,&c);
		add_edge(b+1,a,c);         //多了个-1点 ,故区间总体右移 
	} 
	spfa();
	cout<<dis[50001]<<endl; 
	
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

差分约束 解决区间选点问题 的相关文章

  • IT界头条2022年7月1日版

    2022年7月 1日 1 国家网信办发布 互联网用户账号信息管理规定 8月1日起施行 2 腾讯 QQ 回应大批账号被盗 xff1a 用户扫描不法分子伪造的游戏登录二维码 3 网络安全审查办公室对知网启动网络安全审查 4 俄罗斯对谷歌传播诋毁
  • 数据安全与销毁案例:美国最近发生大规模数据泄露

    据福克斯新闻网6月20日报道 xff0c 一位网络安全专家称 xff0c 美国近日发生一起大规模的选民信息泄露事件 xff0c 将近2亿选民的个人信息遭意外曝光 网络风险研究员克里斯 维克里在其博客文章中表示 xff0c 与美国共和党全国委
  • 回收销毁,IT界头条2022年7月12日版

    2022年7月 12日 1 关于构建数据基础制度更好发挥数据要素作用的意见 审议通过 2 微软在新报告中揭示了俄乌冲突期间的网络战细节 3 西北工业大学遭受境外网络攻击 xff0c 西安警方已立案侦查 4 立陶宛对俄罗斯 禁运 后遭网络攻击
  • 回收销毁,IT界头条2022年7月7日版

    2022年7月 7日 1 关于构建数据基础制度更好发挥数据要素作用的意见 审议通过 2 微软在新报告中揭示了俄乌冲突期间的网络战细节 3 西北工业大学遭受境外网络攻击 xff0c 西安警方已立案侦查 4 立陶宛对俄罗斯 禁运 后遭网络攻击
  • 数据安全与销毁:数据安全已经上升到了国家战略层面

    日前 xff0c 中央全面深化改革委员会审议通过了 关于构建数据基础制度更好发挥数据要素作用的意见 xff08 下称 意见 xff09 xff0c 明确提出 把安全贯穿数据治理全过程 业内专家表示 xff0c 数据安全已经上升到了国家战略层
  • C++用带有默认参数的函数实现,求2个或3个正整数中的最大数

    1 题目要求如下 xff1a C 43 43 用带有默认参数的函数实现 xff0c 求2个或3个正整数中的最大数 2 来吧 xff0c 展示 xff1a include lt iostream gt using namespace std
  • 程序设计思维与实践 Week2 作业B "倒水问题"

    数据 xff1a Sample Input xff1a 2 7 5 2 7 4 Sample Output xff1a fill B pour B A success fill A pour A B fill A pour A B succ
  • armbian的换源

    安装好armbian和众多Linux一样 xff0c 最重要的就是把原来的官方源给替换掉 xff0c 换成国内的源 xff0c 当然个人建议还是把官方的源备份一下以防出错 cp etc apt sources list etc apt so
  • Ubuntu18.04上网断断续续

    刚刚体验了一把Ubuntu18 04 LTS xff0c 有个小问题就是 xff0c 网络链接老是断断续续 后来在这里找到了解决方法 xff1a span class hljs built in sudo span gedit etc pp
  • Coursera Machine Learning 第二周 quiz Octave/Matlab Tutorial 习题答案

    1 Suppose I first execute the following Octave Matlab commands 1 2
  • C语言random问题

    总 结一下C语言random的用法 xff1a srand xff08 xff08 int xff09 time xff08 NULL xff09 xff09 用于设定随机数种子 rand 100 xff0c 产生 0 99 的随机数 如果
  • java.util.regex.PatternSyntaxException

    在处理字符串用到String replaceAll 这个方法的时候出现了这个异常 Exception in thread 34 main 34 java util regex PatternSyntaxException Dangling
  • Shell 脚本 Debug 方法

    可能有的程序员在对程序调试的时候用printf或者echo将信息挨条打印出来 xff0c 但是这比较麻烦 xff0c 因为在交付的时候还要将这些语句一条条删除 xff0c 下面对shell debug的方法稍微做一个总结 xff1a 1 使
  • JAVA 点击按钮展开一个新的Jpanel

    问题不太容易用语言来描述 xff0c 先直接上图吧 xff1a 点击按钮之前 xff1a 点击按钮之后 xff1a 那么如何实现这种功能呢 xff1f 首先在图一中的主JFrame中添加一个JScrollPane xff0c 在点击按钮后n
  • java 实现日历选择器

    首先引用com qt datapicker DatePicker 包实现如下 xff1a package Date import java awt event ActionEvent import java awt event Action
  • 获取JPasswordField组件中的密码

    在JTextField中有一个方法getText xff0c 可以返回组件中输入的字符串 xff0c 但是对于JPasswordField类 xff0c getText 方法已经不适用了 xff0c 执意使用的话 xff0c 获取的也是一串
  • 指针的大小

    说这个之前先了解几个概念 xff1a 字长 xff1a 字长是CPU的主要技术指标之一 xff0c 指的是CPU一次能并行处理的二进制的位数 xff0c 字长是8的整倍数 xff0c 通常的PC机的字长为16位 xff0c 32位 xff0
  • 程序设计思维与实践 Week6 作业A氪金带东树的直径的应用

    题意 xff1a 依次输入图中的点以及边权等信息 xff0c 最后输出每个点在图中所能到达的最远的路线的长度 例如所给的样例 xff1a input 输入文件包含多组测试数据 对于每组测试数据 xff0c 第一行一个整数N N lt 61
  • 《UNIX环境高级编程》(第二版)找不到apue.h问题

    UNIX环境高级编程 xff08 第二版 xff09 这本书 xff0c 实例程序中都包含头文件apue h xff0c 寻找linux usr include中 xff0c 缺找不到此头文件 xff0c 因此编译时会出错 实际上apue
  • java程序中,如何安全的结束一个正在运行的线程?

    如何停止java的线程一直是一个开发多线程程序常遇到的一个问题 在Java的多线程编程中 xff0c java lang Thread类型包含了一些列的方法start stop stop Throwable and suspend dest

随机推荐