【网络流24题22】最长k可重线段集问题
sol
千万!千万!不要理解错题意了!最长K可重,不是说线段最多K可重!你以为计算几何?
原文:使得在\(x\)轴上的任何一点\(p\),\(S\)中与直线\(x=p\)相交的开线段个数不超过\(k\)。
所以这题就和最长K可重区间集问题是一样的!
只是这里有个坑。线段可以垂直\(x\)轴对吧(废话),那么你直接离散化然后连边就会连出一个负边权的自!环!,然后spfa呵呵呵。死掉了。
为了解决这一问题,我们把所有横坐标都扩大两倍,然后左端点++。对于那些左右端点相等的线段,就把左端点++改为左端点--即可。这样既可以保证连接不形成环,且和原本的意义相同。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int N = 1005;
const int inf = 1e9;
struct edge{int to,next,w,cost;}a[N<<2];
int n,k,l[N],r[N],x[N],y[N],val[N],o[N],len,s,t,head[N],cnt=1,dis[N],vis[N],pe[N];
long long ans;
queue<int>Q;
long long sqr(int x){return 1ll*x*x;}
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
void link(int u,int v,int w,int cost)
{
a[++cnt]=(edge){v,head[u],w,cost};
head[u]=cnt;
a[++cnt]=(edge){u,head[v],0,-cost};
head[v]=cnt;
}
bool spfa()
{
memset(dis,63,sizeof(dis));
dis[s]=0;Q.push(s);
while (!Q.empty())
{
int u=Q.front();Q.pop();
for (int e=head[u];e;e=a[e].next)
{
int v=a[e].to;
if (a[e].w&&dis[v]>dis[u]+a[e].cost)
{
dis[v]=dis[u]+a[e].cost;pe[v]=e;
if (!vis[v]) vis[v]=1,Q.push(v);
}
}
vis[u]=0;
}
if (dis[t]==dis[0]) return false;
int sum=inf;
for (int i=t;i!=s;i=a[pe[i]^1].to)
sum=min(sum,a[pe[i]].w);
ans-=1ll*sum*dis[t];
for (int i=t;i!=s;i=a[pe[i]^1].to)
a[pe[i]].w-=sum,a[pe[i]^1].w+=sum;
return true;
}
int main()
{
n=gi();k=gi();
for (int i=1;i<=n;i++)
{
l[i]=gi(),x[i]=gi(),r[i]=gi(),y[i]=gi();
val[i]=sqrt(sqr(r[i]-l[i])+sqr(y[i]-x[i]));
l[i]*=2;r[i]*=2;
if (l[i]==r[i]) l[i]--;
else l[i]++;
o[++len]=l[i];o[++len]=r[i];
}
sort(o+1,o+len+1);
len=unique(o+1,o+len+1)-o-1;
s=len+1;t=len+2;
link(s,1,k,0);link(len,t,k,0);
for (int i=1;i<len;i++)
link(i,i+1,k,0);
for (int i=1;i<=n;i++)
{
l[i]=lower_bound(o+1,o+len+1,l[i])-o;
r[i]=lower_bound(o+1,o+len+1,r[i])-o;
link(l[i],r[i],1,-val[i]);
}
while (spfa()) ;
printf("%lld\n",ans);
return 0;
}
【网络流24题22】最长k可重线段集问题的更多相关文章
- 【网络流24题】最长k可重线段集(费用流)
[网络流24题]最长k可重线段集(费用流) 题面 Cogs的数据有问题 Loj 洛谷 题解 这道题和最长k可重区间集没有区别 只不过费用额外计算一下 但是,还是有一点要注意的地方 这里可以是一条垂直的 ...
- 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...
- *LOJ#6227. 「网络流 24 题」最长k可重线段集问题
$n \leq 500$条平面上的线段,问一种挑选方法,使得不存在直线$x=p$与挑选的直线有超过$k$个交点,且选得的直线总长度最长. 横坐标每个点开一个点,一条线段就把对应横坐标连一条容量一费用( ...
- 网络流24题之最长k可重线段集问题
对于每个线段拆成两个点,如同之前一样建图,由于可能出现垂直于x轴的 所以建图由i指向i~ 继续最小费用最大流 By:大奕哥 #include<bits/stdc++.h> using na ...
- LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 ...
- loj #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 题目描述 给定实直线 L LL 上 n nn 个开区间组成的集合 I II,和一个正整数 k kk,试设计一个算法,从开区间集合 I II 中选 ...
- 【网络流24题】最长k可重区间集(费用流)
[网络流24题]最长k可重区间集(费用流) 题面 Cogs Loj 洛谷 题解 首先注意一下 这道题目里面 在Cogs上直接做就行了 洛谷和Loj上需要判断数据合法,如果\(l>r\)就要交换\ ...
- 【网络流24题】最长k可重区间集问题(费用流)
[网络流24题]最长k可重区间集问题 [问题分析] 最大权不相交路径问题,可以用最大费用最大流解决. [建模方法] 方法1 按左端点排序所有区间,把每个区间拆分看做两个顶点<i.a>< ...
- 网络流24题:最长 k 可重区间集问题题解
最长 k 可重区间集问题题解: 突然想起这个锅还没补,于是来把这里补一下qwq. 1.题意简述: 有\(n\)个开区间,这\(n\)个开区间组成了一个直线\(L\),要求选择一些区间,使得在直线\(L ...
- 【刷题】LOJ 6014 「网络流 24 题」最长 k 可重区间集
题目描述 给定实直线 \(L\) 上 \(n\) 个开区间组成的集合 \(I\) ,和一个正整数 \(k\) ,试设计一个算法,从开区间集合 \(I\) 中选取出开区间集合 \(S \subseteq ...
随机推荐
- 高可用Redis服务架构分析与搭建
基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,我们经常在业务中用其存储用户登陆态(Session存储),加速一些热数据的查询(相比较mysql而言,速度有数量 ...
- php + 和 array_merge的区别
(1)对于+,当key相同时,都是舍弃后面的结果: array_merge ,当key相同时,key是字符,则后面的覆盖前面的:key是数字,则不发生覆盖,会重新建立数组索引. $arr1 = arr ...
- Netty的常用概念
我们先来看一段代码: // Configure the server. EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGr ...
- LINUX服务器下用root登录ftp
因为安全方面的原因,root用户是默认不能登录ftp服务的. 如果一定要用root登录,则: 1.删除或注释/etc/vsftpd.ftpusers中的root 2.删除或注释/etc/vsftpd. ...
- 隱藏在素數規律中的Pi -- BZOJ1041解題報告
退役狗在刷程書的過程中看到了一個有趣的視頻, 講解了一個有趣的問題. 在網上隨便搜索了一下居然還真的找到了一道以它爲背景的OI題目, BZOJ1041. 下面的內容會首先回顧一下視頻所討論的知識, 有 ...
- [原创]CentOS7安装远程工具teamviewer12
系统环境:CentOS 7.0.1 1.下载安装# wget https://dl.tvcdn.de/download/version_12x/teamviewer_12.0.85001.i686.r ...
- Angular:利用内容投射向组件输入ngForOf模板
现在,我们写一个组件puppiesListCmp,用于显示小狗狗的列表: //puppies-list.component.ts @Component({ selector: 'puppies-lis ...
- 如何使用 VS生成动态库?
如何使用 VS生成动态库? //.cpp 文件默认定义了 __cplusplus 宏 #ifdef __cplusplus extern "C"{ #endif xxx #ifde ...
- dd命令的巧妙使用
dd是一个非常使用高效的命令,他的作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 一.备份 备份整个磁盘到磁盘 #将sdx整盘备份到sdy中去 dd if=/dev/sdx of=/ ...
- Centos小白命令
centos在登录界面无法输入密码 Centos安装flash插件 Centos挂载windows ntfs分区 Centos搭建Eclipse C/C++环境 windows下的txt文件在cent ...