最长k可重线段集问题

时空限制1000ms / 128MB

题目描述

给定平面 x−O−y 上 n 个开线段组成的集合 I,和一个正整数 k 。试设计一个算法,从开线段集合 I 中选取出开线段集合 S⊆I ,使得在 x 轴上的任何一点 p,S 中与直线 x=p 相交的开线段个数不超过 k,且∑​∣z∣达到最大。这样的集合 S 称为开线段集合 I 的最长 k 可重线段集。∑​∣z∣ 称为最长 k 可重线段集的长度。

对于任何开线段 z,设其断点坐标为 (x0​,y0​) 和 (x1​,y1​),则开线段 z 的长度 ∣z∣ 定义为:|z|=⌊sqrt{(x1-x0)^2+(y1-y0)^2}⌋

对于给定的开线段集合 I 和正整数 k,计算开线段集合 I 的最长 k 可重线段集的长度。

输入输出格式

输入格式:

文件的第一 行有 2 个正整数 n 和 k,分别表示开线段的个数和开线段的可重叠数。

接下来的 n 行,每行有 4 个整数,表示开线段的 2 个端点坐标。

输出格式:

程序运行结束时,输出计算出的最长 k 可重线段集的长度。

输入输出样例

输入样例:

4 2
1 2 7 3
6 5 8 3
7 8 10 5
9 6 13 9
输出样例:

17

说明

1≤n≤500

1≤k≤13

题目链接:https://www.luogu.org/problemnew/show/P3357


最大权不相交路径。和这一题很类似。但是这一题会出现线段垂直x轴的情况,这样就会出现自环,而且是负环,所以直接跑费用流会有问题。因此要对每一个点进行拆点,拆成1号点和2号点,具体连边操作为:每个点和下一个点之间连一条费用为0,容量为INF的边。对于某线段,设其在x轴上投影的左右端点为点u和点v,若u=v,则在这个点的1号点和2号点之间连一条费用为边权,容量为1的边,否则在u的2号点和v的1号点之间连一条边。

#include<bits/stdc++.h>
#define INF LLONG_MAX/2
#define N 3005
using namespace std; struct ss
{
int u,v,next;
long long flow,cost;
}; ss edg[N*];
int head[N],now_edge=; void addedge(int u,int v,long long flow,long long cost)
{
edg[now_edge]=(ss){u,v,head[u],flow,cost};
head[u]=now_edge++;
edg[now_edge]=(ss){v,u,head[v],,-cost};
head[v]=now_edge++;
} int spfa(int s,int t,long long &flow,long long &cost)
{
int vis[N]={};
vis[s]=;
queue<int>q;
q.push(s);
long long dis[N];
for(int i=;i<N;i++)dis[i]=INF;
dis[s]=;
int pre[N]={};
long long addflow[N]={};
addflow[s]=INF; while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=; for(int i=head[now];i!=-;i=edg[i].next)
{
ss e=edg[i];
if(e.flow>&&dis[e.v]>dis[now]+e.cost)
{
dis[e.v]=dis[now]+e.cost;
pre[e.v]=i;
addflow[e.v]=min(e.flow,addflow[now]);
if(!vis[e.v])
{
q.push(e.v);
vis[e.v]=;
}
}
}
} if(dis[t]==INF)return ; flow+=addflow[t];
cost+=addflow[t]*dis[t]; int now=t;
while(now!=s)
{
edg[pre[now]].flow-=addflow[t];
edg[pre[now]^].flow+=addflow[t];
now=edg[pre[now]].u;
}
return ; } void mcmf(int s,int t,long long &flow,long long &cost)
{
while(spfa(s,t,flow,cost));
} void init()
{
now_edge=;
memset(head,-,sizeof(head));
} long long x[N][];
long long LSH[N];
int size_lsh=; int f(long long x)
{
return lower_bound(LSH,LSH+size_lsh,x)-LSH+;
} long long dist(long long x[])
{
double now=(x[]-x[])*(x[]-x[])+(x[]-x[])*(x[]-x[]);
now=sqrt(now);
return (long long)now;
} int main()
{
init();
int n,k;
scanf("%d %d",&n,&k);
for(int i=;i<=n;i++)
for(int j=;j<;j++)
{
scanf("%lld",&x[i][j]);
if(j%==)LSH[size_lsh++]=x[i][j];
} sort(LSH,LSH+size_lsh);
size_lsh=unique(LSH,LSH+size_lsh)-LSH; int s=size_lsh*+,t=s+; for(int i=;i<size_lsh*;i++)addedge(i,i+,INF,);
addedge(s,,k,);
addedge(size_lsh*,t,INF,); for(int i=;i<=n;i++)
{
int u=min(f(x[i][]),f(x[i][])),v=max(f(x[i][]),f(x[i][]));
long long w=dist(x[i]); if(u!=v)addedge(u*,v*-,,-w);
else
addedge(*u-,*v,,-w);
}
long long flow=,cost=;
mcmf(s,t,flow,cost);
printf("%lld\n",-cost);
return ;
}

网络流24题-最长k可重线段集问题的更多相关文章

  1. [网络流24题]最长k可重线段集[题解]

    最长 \(k\) 可重线段集 题目大意 给定平面 \(x-O-y\) 上 \(n\) 个开线段组成的集合 \(I\) ,和一个正整数 \(k\) .试设计一个算法,从开线段集合 \(I\) 中选取开线 ...

  2. [网络流24题] 最长k可重线段集问题 (费用流)

    洛谷传送门 LOJ传送门 最长k可重区间集问题的加强版 大体思路都一样的,不再赘述,但有一些细节需要注意 首先,坐标有负数,而且需要开$longlong$算距离 但下面才是重点: 我们把问题放到了二维 ...

  3. COGS743. [网络流24题] 最长k可重区间集

    743. [网络流24题] 最长k可重区间集 ★★★   输入文件:interv.in   输出文件:interv.out   简单对比时间限制:1 s   内存限制:128 MB «问题描述: «编 ...

  4. [网络流24题]最长k可重区间集[题解]

    最长 \(k\) 可重区间集 题目大意 给定实心直线 \(L\) 上 \(n\) 个开区间组成的集合 \(I\) ,和一个正整数 \(k\) ,试设计一个算法,从开区间集合 \(I\) 中选取开区间集 ...

  5. [网络流24题] 最长k可重区间集

    https://www.luogu.org/problemnew/show/3358 以区间(1,5),(2,6),(7,8)为例 建模方法一: 建模方法二: 离散化区间端点 相当于找k条费用最大的不 ...

  6. [网络流24题] 最长K可重区间集问题

    题目链接:戳我 当时刷24题的时候偷了懒,没有写完,结果落下这道题没有写qwq结果今天考试T3中就有一部分要用到这个思想,蒟蒻我硬是没有想到网络流呜呜呜 最大费用流. 就是我们考虑将问题转化一下,转化 ...

  7. [网络流24题] 最长k可重区间集问题 (费用流)

    洛谷传送门 LOJ传送门 很巧妙的建图啊...刚了$1h$也没想出来,最后看的题解 发现这道题并不类似于我们平时做的网络流题,它是在序列上的,且很难建出来二分图的形. 那就让它在序列上待着吧= = 对 ...

  8. 【网络流24题】最长k可重线段集(费用流)

    [网络流24题]最长k可重线段集(费用流) 题面 Cogs的数据有问题 Loj 洛谷 题解 这道题和最长k可重区间集没有区别 只不过费用额外计算一下 但是,还是有一点要注意的地方 这里可以是一条垂直的 ...

  9. 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题

    题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...

随机推荐

  1. Mysql 8.0 新特性

    转载:https://www.jianshu.com/p/be29467c2b0c

  2. 【转】EM算法原理

    EM是我一直想深入学习的算法之一,第一次听说是在NLP课中的HMM那一节,为了解决HMM的参数估计问题,使用了EM算法.在之后的MT中的词对齐中也用到了.在Mitchell的书中也提到EM可以用于贝叶 ...

  3. VC下的C语言程序随机数的产生

    本文章适用于VC编译器,VC编译器里有个rand()函数,我们用它来实现取随机数. #include <stdio.h> #include<stdlib.h> //随机数的头文 ...

  4. Python学习笔记5(函数)

    [摘要]本文详细介绍python中的函数,以及与之相关的参数和作用域的概念,并介绍递归的概念以及在程序中的应用. 函数定义 定义函数要用函数定义语句def.如下: def hello(name): r ...

  5. Unity基础-脚本的基本使用

    脚本的基本使用 定义与挂载monobehaviour 1.新建一个场景 2.新建脚本 using System.Collections; using System.Collections.Generi ...

  6. JAVA基础篇—文件与流

    处理字节流的抽象类 InputStream 是字节输入流的所有类的超类,一般我们使用它的子类,如FileInputStream等. OutputStream是字节输出流的所有类的超类,一般我们使用它的 ...

  7. LeetCode(122) Best Time to Buy and Sell Stock II

    题目 Say you have an array for which the ith element is the price of a given stock on day i. Design an ...

  8. 如何提高UDP的可靠性

    TCP是通过确认机制和超时重传机制实现可靠传输 UDP UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频.视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数 ...

  9. 树状数组:CDOJ1583-曜酱的心意(树状数组心得)

    曜酱的心意 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 131072/131072KB (Java/Others) Description ...

  10. JQuery根据字母检索元素并导航到指定位置

    介绍:类似于实现ios通讯录中右侧字母,快速导航到联系人的效果,如图: Html代码如下,分别是字母和港星名字的排序: <input type="text" id=" ...