首页 > 其他分享 >【题解】P3358 最长k可重区间集问题

【题解】P3358 最长k可重区间集问题

时间:2022-12-12 11:46:35浏览次数:40  
标签:可重 mathbf int 题解 P3358 tail text 开区间

最长k可重区间集问题

题目描述

给定实直线 \(\text{L}\) 上 \(n\) 个开区间组成的集合 \(\mathbf{I}\),和一个正整数 \(k\),试设计一个算法,从开区间集合 \(\mathbf{I}\) 中选取出开区间集合 \(\mathbf{S}\subseteq\mathbf{I}\),使得在实直线 \(\text{L}\) 上的任意一点 \(x\),\(\text{S}\) 中包含 \(x\) 的开区间个数不超过 \(k\),且 \(\sum_{z\in\text{S}}\lvert z\rvert\) 达到最大(\(\lvert z\rvert\) 表示开区间 \(z\) 的长度)。

这样的集合 \(\mathbf{S}\) 称为开区间集合 \(\mathbf{I}\) 的最长 \(k\) 可重区间集。\(\sum_{z\in\text{S}}\lvert z\rvert\) 称为最长 \(k\) 可重区间集的长度。

对于给定的开区间集合 \(\mathbf{I}\) 和正整数 \(k\),计算开区间集合 \(\mathbf{I}\) 的最长 \(k\) 可重区间集的长度。

输入格式

输入的第一行有 \(2\) 个正整数 \(n\) 和 \(k\),分别表示开区间的个数和开区间的可重叠数。接下来的 \(n\) 行,每行有 \(2\) 个整数,表示开区间的左右端点坐标 \(l,r\),数据保证 \(l<r\)。

输出格式

输出最长 \(k\) 可重区间集的长度。

样例 #1

样例输入 #1

4 2
1 7
6 8
7 10
9 13

样例输出 #1

15

提示

对于 \(100\%\) 的数据,\(1\le n\le 500\),\(1\le k\le 3\)。

题解

考虑某点重叠不超过 $ k $ 和网络流中的流量限制非常相似,于是可以类似建图:

  • 离散化
  • 每个区间左端点向右端点连一条价值为 \(len\) ,流量为\(1\)的边
  • 离散化后的点每点向其右边的点连一条流量为\(k\),价值为\(0\)的边.
  • 从原点释放\(k\)的流量

直接跑费用流即可。

此题启发我们网络流的题目思考每一条流的意义是什么,同时要注意找增广路的过程实际和反悔过程同时进行

点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int rd(){
	int f=1,j=0;
	char w=getchar();
	while(!isdigit(w)){
		if(w=='-')f=-1;
		w=getchar();
	}
	while(isdigit(w)){
		j=j*10+w-'0';
		w=getchar();
	}
	return f*j;
}

const int N=5001,M=200001;
int head[N],to[M],fro[M],val[M],flo[M],tail=1;
int n,K,fl[N],va[N];
int s,t,cnt,ans;
int dig[N],tot,L[N],R[N],par[N],fr[N],fa[N];
bool inque[N];

inline void addlin(int x,int y,int a,int b){
	to[++tail]=y;
	fro[tail]=head[x];
	head[x]=tail;
	flo[tail]=a,val[tail]=b;
	to[++tail]=x;
	fro[tail]=head[y];
	head[y]=tail;
	flo[tail]=0,val[tail]=-b;
	return ;
}
bool spfa(int last){
	deque<int>p;
	for(int i=1;i<=cnt;i++)fl[i]=inque[i]=fr[i]=fa[i]=0,va[i]=-1;
	fl[s]=last,va[s]=0;
	p.push_back(s);
	while(!p.empty()){
		int u=p.front();p.pop_front();
		inque[u]=false;
		for(int k=head[u];k;k=fro[k]){
			int x=to[k];
			if(!flo[k]||va[x]>=va[u]+val[k])continue;
			va[x]=va[u]+val[k];
			fl[x]=min(fl[u],flo[k]);
			fr[x]=k,fa[x]=u;
			if(!inque[x])inque[x]=true,p.push_back(x); 
		}
	}
	return fl[t]!=0;
}

signed main(){
	n=rd(),K=rd();
	s=++cnt,t=++cnt;
	for(int i=1;i<=n;i++)L[i]=dig[++tot]=rd(),R[i]=dig[++tot]=rd();
	sort(dig+1,dig+1+tot);
	tot=unique(dig+1,dig+1+tot)-dig-1;
	for(int i=0;i<=tot;i++)par[i]=++cnt;
	for(int i=1;i<=tot;i++)addlin(par[i-1],par[i],K,0);
	addlin(s,par[0],K,0),addlin(par[tot],t,K,0);
	for(int i=1;i<=n;i++){
		int len=R[i]-L[i];
		L[i]=lower_bound(dig+1,dig+1+tot,L[i])-dig;
		R[i]=lower_bound(dig+1,dig+1+tot,R[i])-dig;
		addlin(par[L[i]],par[R[i]],1,len);
	}
	while(K&&spfa(K)){
		K-=fl[t];
		ans+=fl[t]*va[t];
		for(int u=t;u!=s;u=fa[u]){
			flo[fr[u]]-=fl[t];
			flo[fr[u]^1]+=fl[t];
		}
	}
	printf("%d",ans);
	return 0;
}

标签:可重,mathbf,int,题解,P3358,tail,text,开区间
From: https://www.cnblogs.com/T-water/p/16975613.html

相关文章

  • [ Linux ] 可重入函数,volatile 关键字,SIGCHLD信号
    1.可重入函数在数据结构初阶时我们学习过链表,其中当然也学习过链表头插。在此我们复习一下链表头插,我们使用画图来演示。newnode->next=head->next;head->next=newnode;......
  • 洛谷 P1786 帮贡排序 题解
    原题链接P1786帮贡排序解析实现方法一看题:这不就是道排序吗?但是——用啥办法呢?这自带的排序方法,肯定是不能用了那么我们就来写一个cmp排序函数吧!但是——输出排......
  • 题解 洛谷 P2885 [USACO07NOV]Telephone Wire G
    1.题面描述题目链接给出\(n\)棵树的高度。你可以进行任意次操作,每次操作形如:把某棵树增高\(x\),代价为\(x^2\)(注意:不能将一棵树的高度减少)。在操作完之后,一个状态......
  • 题解 洛谷 P3594 [POI2015] WIL
    1.题面描述题目链接给定一个长度为\(n\)的序列,你有一次机会选中一段连续的长度不超过\(d\)的区间,将里面所有数字全部修改为\(0\)。请找到最长的一段连续区间,使得该......
  • 题解 CodeForces 940E Cashback
    1.题面描述题目链接给定长为\(n\)的序列和一个整数\(c\),你需要将其分为若干段。对于每一段,若其长度为\(k\),则可以删除其中前\(\lfloor\frac{k}{c}\rfloor\)小的......
  • 题解 洛谷 P3793 由乃救爷爷
    1.题面描述题目链接给定长为\(n\)的序列,\(m\)次询问,查询区间最大值。\(n,m\le10^7\),数据随机。2.分析经典的静态区间最小值问题,经典题目配经典算法,考虑到ST表......
  • NOIP2022 题解
    A.种花枚举\((x_2,y_0)\),考虑\(x_1\)可能在哪些位置,显然是在\(x_2\)往上的一个极长连续0段上。考虑如果固定了\(x_1\)的位置后怎么计算C形的数量,我们预处理......
  • CF1182E 题解
    前言题目传送门!更好的阅读体验?\(\text{zltqwq}\)推荐矩阵快速幂题目。思路......
  • P4902 乘积 题解
    乘积给出\(A\),\(B\),求下面的式子的值.\[\prod_{i=A}^{B}\prod_{j=1}^{i}(\frac{i}{j})^{\left\lfloor\frac{i}{j}\right\rfloor}\(\bmod\19260817)\]包含\(T\)组......
  • 【题解】CF1764C Doremy's City Construction
    题目传送门思路首先我们思考一个性质,由于不能有连续单调不升/不降的三个点连在一起,所以对于单个点来讲,显然要么只和比它大的连边(称为A类点),要么只和比它小的连边(称为B类点......