【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述
给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法。
从开线段集合 \(\text{I}\) 中选取出开线段集合 \(\text{S}\in \text{I}\) ,
使得在x轴上的任何一点 \(\text{p}\) , \(\text{S}\) 中与直线 \(\text{x}=\text{p}\) 相交的开线段个数不超过 \(\text{k}\) ,
且 \(\sum_{\text{z} \in \text{S}}|z|\) 达到最大。
这样的集合 \(\text{S}\) 称为开线段集合 \(\text{I}\) 的最长 \(\text{k}\) 可重线段集的长度。
对于任何开线段 \(\text{z}\) ,设其断电坐标为 \(( x_0 , y_0 )\) 和 \(( x_1 , y_1 )\) ,
则开线段 \(\text{z}\) 的长度 \(|\text{z}|\) 定义为:\(|z| = \lfloor \sqrt{ ( x_1 - x_0 ) ^ 2 + ( y_1 - y_0 )^2 } \rfloor\)
对于给定的开线段集合 \(\text{I}\) 和正整数 \(\text{k}\) ,计算开线段集合 \(\text{I}\) 的最长 \(\text{k}\) 可重线段集的长度。
输入格式
文件的第一 行有二个正整数 \(\text{n}\) 和 \(\text{k}\) ,分别表示开线段的个数和开线段的可重迭数。接下来的 \(\text{n}\) 行,每行有4个整数,表示开线段的2个端点坐标。
输出格式
程序运行结束时,输出计算出的最长k可重线段集的长度。
样例
样例输入
4 2
1 2 7 3
6 5 8 3
7 8 10 5
9 6 13 9
样例输出
17
数据范围与提示
\(1\leq n\leq500\)
\(1 \leq k \leq 13\)
题解
这道题与【刷题】LOJ 6014 「网络流 24 题」最长 k 可重区间集有很大的相似度
这里基于明白那道题的做法之上给出这道题的做法
把线段对应到 \(x\) 轴上,其实就变成了一些区间了,和那道题一样
但是有一种特殊情况,就是存在线段 \(x=r\) 的时候,如果按照那题的方式建图,就会出现自环,所以要换一种建图方式
考虑把每个区间的左右端点都变成 \(2\) 倍(离散化后),如果 \(l=r\) ,那么 \(r\) 加一,否则 \(l\) 加一,这样就可以防止自环的出现(想一想为什么)
然后同样的方式跑答案就好了
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=2000+10,MAXM=(MAXN<<1),inf=0x3f3f3f3f;
int n,k,r,e=1,s,t,beg[MAXN],cur[MAXN],L[MAXN],R[MAXN],vis[MAXN],level[MAXN],p[MAXN],nex[MAXM<<1],to[MAXM<<1],cap[MAXM<<1],was[MAXM<<1],clk;
ll answas,val[MAXN];
std::queue<int> q;
std::vector<int> V;
std::map<int,int> M;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y,int z,int w)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
cap[e]=z;
was[e]=w;
to[++e]=x;
nex[e]=beg[y];
beg[y]=e;
cap[e]=0;
was[e]=-w;
}
inline void discretization()
{
for(register int i=1;i<=n;++i)V.push_back(L[i]),V.push_back(R[i]);
std::sort(V.begin(),V.end());
V.erase(std::unique(V.begin(),V.end()),V.end());
for(register int i=0,lt=V.size();i<lt;++i)M[V[i]]=i+1;
for(register int i=1;i<=n;++i)L[i]=M[L[i]],R[i]=M[R[i]],chkmax(r,R[i]);
}
inline bool bfs()
{
memset(level,inf,sizeof(level));
level[s]=0;
p[s]=1;
q.push(s);
while(!q.empty())
{
int x=q.front();
q.pop();
p[x]=0;
for(register int i=beg[x];i;i=nex[i])
if(cap[i]&&level[to[i]]>level[x]+was[i])
{
level[to[i]]=level[x]+was[i];
if(!p[to[i]])p[to[i]]=1,q.push(to[i]);
}
}
return level[t]!=inf;
}
inline int dfs(int x,int maxflow)
{
if(x==t||!maxflow)return maxflow;
vis[x]=clk;
int res=0;
for(register int &i=cur[x];i;i=nex[i])
if((vis[to[i]]^vis[x])&&cap[i]&&level[to[i]]==level[x]+was[i])
{
int f=dfs(to[i],min(maxflow,cap[i]));
res+=f;
cap[i]-=f;
cap[i^1]+=f;
answas+=1ll*f*was[i];
maxflow-=f;
if(!maxflow)break;
}
vis[x]=0;
return res;
}
inline void MCMF()
{
while(bfs())clk++,memcpy(cur,beg,sizeof(cur)),dfs(s,inf);
}
int main()
{
read(n);read(k);
for(register int i=1;i<=n;++i)
{
int x1,y1,x2,y2;read(x1);read(y1);read(x2);read(y2);
val[i]=std::sqrt(1ll*(x1-x2)*(x1-x2)+1ll*(y1-y2)*(y1-y2));
L[i]=(x1<<1),R[i]=(x2<<1);
if(L[i]>R[i])std::swap(L[i],R[i]);
if(L[i]==R[i])R[i]++;
else L[i]++;
}
discretization();
s=r+1,t=s+1;
insert(s,1,k,0);insert(r,t,k,0);
for(register int i=1;i<r;++i)insert(i,i+1,inf,0);
for(register int i=1;i<=n;++i)insert(L[i],R[i],1,-val[i]);
MCMF();
write(-answas,'\n');
return 0;
}
【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题的更多相关文章
- *LOJ#6227. 「网络流 24 题」最长k可重线段集问题
$n \leq 500$条平面上的线段,问一种挑选方法,使得不存在直线$x=p$与挑选的直线有超过$k$个交点,且选得的直线总长度最长. 横坐标每个点开一个点,一条线段就把对应横坐标连一条容量一费用( ...
- [luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划
[luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划 试题描述 一个餐厅在相继的 \(N\) 天里,第 \(i\) 天需要 \(R_i\) 块餐巾 \((i=l,2,-,N)\) ...
- [LOJ#6002]「网络流 24 题」最小路径覆盖
[LOJ#6002]「网络流 24 题」最小路径覆盖 试题描述 给定有向图 G=(V,E).设 P 是 G 的一个简单路(顶点不相交)的集合.如果 V 中每个顶点恰好在 P 的一条路上,则称 P 是 ...
- loj #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 题目描述 给定实直线 L LL 上 n nn 个开区间组成的集合 I II,和一个正整数 k kk,试设计一个算法,从开区间集合 I II 中选 ...
- LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 ...
- 【网络流24题】最长k可重线段集(费用流)
[网络流24题]最长k可重线段集(费用流) 题面 Cogs的数据有问题 Loj 洛谷 题解 这道题和最长k可重区间集没有区别 只不过费用额外计算一下 但是,还是有一点要注意的地方 这里可以是一条垂直的 ...
- 网络流24题-最长k可重线段集问题
最长k可重线段集问题 时空限制1000ms / 128MB 题目描述 给定平面 x−O−y 上 n 个开线段组成的集合 I,和一个正整数 k .试设计一个算法,从开线段集合 I 中选取出开线段集合 S ...
- [网络流24题]最长k可重线段集[题解]
最长 \(k\) 可重线段集 题目大意 给定平面 \(x-O-y\) 上 \(n\) 个开线段组成的集合 \(I\) ,和一个正整数 \(k\) .试设计一个算法,从开线段集合 \(I\) 中选取开线 ...
- loj #6013. 「网络流 24 题」负载平衡
#6013. 「网络流 24 题」负载平衡 题目描述 G 公司有 n nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n nn 个仓库的库存数量相同.搬运货物时 ...
随机推荐
- odoo之自动生成编号问题
单独的seq.xml文件 <?xml version="1.0" encoding="utf-8"?><openerp> <dat ...
- 20155227《网络对抗》Exp2 后门原理与实践
20155227<网络对抗>Exp2 后门原理与实践 基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? 在非官方网站下载软件时,后门很可能被捆绑在软件中. 攻击者利用欺 ...
- 【第三方插件】使用Topshelf创建Windows服务
概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的 ...
- OFS环境,删除Resource 时出现错误失败,应该如何继续
From the Windows failover cluster manager,select the group listener, stop it, and delete it. Do the ...
- Bluedroid协议栈BTU线程处理HCI数据流程分析
在蓝牙enable的过程中会进行多个线程的创建以及将线程与队列进行绑定的工作.该篇文章主要分析一下处理hci数据这个 线程. void BTU_StartUp(void) { ... btu_bta_ ...
- Android与单片机通信常用数据转换方法(汇总)
下面直接贴代码 1. 将GB2312转化为中文,如BAFAC2DCB2B7→胡萝卜,两个字节合成一个文字 public static String stringToGbk(String string ...
- Hexo站点之域名配置【2】
该系列博客列表请访问:http://www.cnblogs.com/penglei-it/category/934299.html 摘要 因为Hexo个人博客是托管在github之上,每次访问都要使用 ...
- 接口自动化测试框架-AIM
最近在做公司项目的自动化接口测试,在现有几个小框架的基础上,反复研究和实践,搭建了新的测试框架.利用业余时间,把框架总结了下来. AIM框架介绍 AIM,是Automatic Interface Mo ...
- 手机Gmail上用Exchange协议配置收发QQ邮箱
1.开启Exchange服务 2.生成授权码(登录密码) 3."服务器"填入ex.qq.com
- LeetCode-3.无重复字符的最长字串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...