洛谷P3358 最长k可重区间集问题(费用流)
因为一个zz错误调了一个早上……汇点写错了……spfa也写错了……好吧好像是两个……
把数轴上的每一个点向它右边的点连一条边,容量为$k$,费用为$0$,然后把每一个区间的左端点向右端点连边,容量为$1$,费用为区间长度,然后求一个最大费用最大流。因为坐标太大,记得离散
然而并不是很明白为什么这样做是对的……想了想,把网络流当成一个水流好了,水从左流到右,那么如果是在一个区间内,不可能满流(因为被区间左端点至右端点那一条边给分去了一部分流),但是被分去的那一部分流会在区间右端点被流回来,所以不想交的区间是没有影响的(因为是开区间,所以右端点和另一区间左端点重合并没有影响)。然后如果区间内还有其他区间的左端点,又会分流,一直这样下去,直到有超过$k$个区间覆盖了同一点,那样流就不够了,不会再分(因为从源点也只有$k$的流),那么只要求出了一个最大流,就是一个满足题目条件的方案。又因为要使长度最大,那么我们要让区间的流带上费用,求一个最大费用流即可
//minamoto
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=;
int ver[M],Next[M],head[N],edge[M],flow[M],tot=;
int dis[N],disf[N],Pre[N],last[N],vis[N],n,s,t,k;
inline void add(int u,int v,int f,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=,edge[tot]=-e;
}
bool spfa(){
queue<int> Q;
memset(dis,0xef,sizeof(dis));
Q.push(s),dis[s]=,vis[s]=,disf[s]=inf,Pre[t]=-;
while(!Q.empty()){
int u=Q.front();Q.pop();vis[u]=;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(flow[i]>&&dis[v]<dis[u]+edge[i]){
dis[v]=dis[u]+edge[i],Pre[v]=u;
last[v]=i,disf[v]=min(disf[u],flow[i]);
if(!vis[v]) vis[v]=,Q.push(v);
}
}
}
return Pre[t]!=-;
}
int dinic(){
int maxflow=,maxcost=;
while(spfa()){
int u=t;
maxflow+=disf[t],maxcost+=disf[t]*dis[t];
while(u!=s){
flow[last[u]]-=disf[t];
flow[last[u]^]+=disf[t];
u=Pre[u];
}
}
return maxcost;
}
struct node{
int l,r,v;
node(){}
node(int l,int r,int v):l(l),r(r),v(v){}
}q[N];
int st[N],m=;
int main(){
n=read(),k=read();
for(int i=;i<=n;++i){
int l=read(),r=read();
if(l>r) swap(l,r);
q[i]=node(l,r,r-l);
st[++m]=l,st[++m]=r;
}
sort(st+,st++m);
m=unique(st+,st++m)-st-;
for(int i=;i<=n;++i){
q[i].l=lower_bound(st+,st++m,q[i].l)-st;
q[i].r=lower_bound(st+,st++m,q[i].r)-st;
}
s=,t=m+;
for(int i=s;i<t;++i) add(i,i+,k,);
for(int i=;i<=n;++i) add(q[i].l,q[i].r,,q[i].v);
printf("%d\n",dinic());
return ;
}
洛谷P3358 最长k可重区间集问题(费用流)的更多相关文章
- 洛谷P3358 最长k可重区间集问题(费用流)
题目描述 对于给定的开区间集合 I 和正整数 k,计算开区间集合 I 的最长 k可重区间集的长度. 输入输出格式 输入格式: 的第 1 行有 2 个正整数 n和 k,分别表示开区间的个数和开区间的可重 ...
- 洛谷P3357 最长k可重线段集问题(费用流)
题目描述 给定平面 x-O-yx−O−y 上 nn 个开线段组成的集合 II ,和一个正整数 kk .试设计一个算法,从开线段集合 II 中选取出开线段集合 S\subseteq IS⊆I ,使得在 ...
- 洛谷 P3358 最长k可重区间集问题 【最大费用最大流】
同 poj 3680 https:www.cnblogs.com/lokiii/p/8413139.html #include<iostream> #include<cstdio&g ...
- 【网络流24题】最长k可重区间集(费用流)
[网络流24题]最长k可重区间集(费用流) 题面 Cogs Loj 洛谷 题解 首先注意一下 这道题目里面 在Cogs上直接做就行了 洛谷和Loj上需要判断数据合法,如果\(l>r\)就要交换\ ...
- [网络流24题] 最长k可重区间集问题 (费用流)
洛谷传送门 LOJ传送门 很巧妙的建图啊...刚了$1h$也没想出来,最后看的题解 发现这道题并不类似于我们平时做的网络流题,它是在序列上的,且很难建出来二分图的形. 那就让它在序列上待着吧= = 对 ...
- 网络流 P3358 最长k可重区间集问题
P3358 最长k可重区间集问题 题目描述 对于给定的开区间集合 I 和正整数 k,计算开区间集合 I 的最长 k可重区间集的长度. 输入输出格式 输入格式: 的第 1 行有 2 个正整数 n和 k, ...
- 【网络流24题】最长k可重线段集(费用流)
[网络流24题]最长k可重线段集(费用流) 题面 Cogs的数据有问题 Loj 洛谷 题解 这道题和最长k可重区间集没有区别 只不过费用额外计算一下 但是,还是有一点要注意的地方 这里可以是一条垂直的 ...
- 洛谷P3357 最长k可重线段集问题(费用流)
传送门 其实和最长k可重区间集问题差不多诶…… 把这条开线段给压成x轴上的一条线段,然后按上面说的那种方法做即可 然而有一个坑点是线段可以垂直于x轴,然后一压变成一个点,连上正权环,求最长路……然后s ...
- 洛谷 P3357 最长k可重线段集问题【最大流】
pre:http://www.cnblogs.com/lokiii/p/8435499.html 和最长k可重区间集问题差不多,也就是价值的计算方法不一样,但是注意这里可能会有x0==x1的情况也就是 ...
随机推荐
- 第十一章 SpringMvc(待续)
············
- ADO.NET主要组件
- C# RSA的加解密与签名验证
最近做了一个CS架构的序列号生成器,用到 RSA加解密技术,以下是RSA的使用方法 RSA加密算法是一种非对称加密算法.在公钥加密标准和电子商业中RSA被广泛使用.RSA是1977年由罗纳德•李维斯特 ...
- NPOI-WebForm_Excel导入与导出
本文面对的是第一次 接触NPOI的童鞋 不必为了一些琐碎的事情搞的心情烦躁 废话不多说先上 Demo 的全家福 接下来直接上代码 public partial class _Default : Sys ...
- Python基础学习四 列表、元组、字典、集合
列表list,用中括号“[ ]”表示 1.任意对象的有序集合 列表是一组任意类型的值,按照一定顺序组合而成的 2.通过偏移读取 组成列表的值叫做元素(Elements).每一个元素被标识一个索引,第一 ...
- SSM框架整合(Spring+SrpingMVC+Mybatis) 简单案例
简介: SSM框架是Spring,SpringMVC 和Mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,dao层四层. Spring实现 ...
- 主机不能访问虚拟机中的web服务【解决方案】
百度了其它一些方法都不行,最后实在没辙,关了windows防火墙和Linux防火墙,居然能够访问了,我服. 总结一下,原来是Red Hat Linux 6.0防火墙没有开启端口80,开启的方法为(老版 ...
- c++多线程编程(一)
C++本身并没有提供任何多线程机制,但是在windows下,我们可以调用SDK win32 api来编写多线程的程序,下面就此简单的讲一下: 创建线程的函数 HANDLE CreateThread( ...
- ZOJ 3956 Course Selection System
题意 有n节课可供选择,每节课都有两个值Hi和Ci,如果学生选择了m节课(x1,x2,....,xm),则它的舒适值被定义为: //这里没有公式((lll¬ω¬)),因为那个图片我保存不下来≧ ﹏ ≦ ...
- laravel 中的Gates,以及修改模型
Gates 是一个用于判断用户是否有权进行某项操作的闭包,通常使用Gate 门面定义在 App\Providers\AuthServiceProvider类中.Gates 总是接收用户实例作为第一个参 ...