洛谷传送门 LOJ传送门

最长k可重区间集问题的加强版

大体思路都一样的,不再赘述,但有一些细节需要注意

首先,坐标有负数,而且需要开$longlong$算距离

但下面才是重点:

我们把问题放到了二维平面内,如果出现了垂直于$x$轴的线段,该如何处理呢?直接当成线段处理显然不可取

假设这条线段的横坐标是$x$

1.它不会对从$x$开始的倾斜线段产生任何影响,但会和穿过$x$的倾斜直线抢位置

2.它会和同样在$x$垂直的线段抢位置

我用了一个比较笨的做法,先把横坐标离散,再把离散后的横坐标抻成原来的$2$倍,垂直线段横坐标为$2x-1$,倾斜线段横坐标是$2x$,问题就被解决了

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define N1 2005
 6 #define M1 200010
 7 #define ll long long
 8 #define dd double
 9 #define inf 0x3f3f3f3f
10 #define maxn 100000
11 using namespace std;
12
13 int gint()
14 {
15     int ret=0,fh=1;char c=getchar();
16     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
17     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
18     return ret*fh;
19 }
20 int n,K,S,T;
21 struct Edge{
22 int head[N1],to[M1<<1],nxt[M1<<1],flow[M1<<1],dis[M1<<1],cte;
23 void ae(int u,int v,int F,int D)
24 {
25     cte++; to[cte]=v; flow[cte]=F; dis[cte]=D;
26     nxt[cte]=head[u]; head[u]=cte;
27 }
28 }e;
29
30 int que[M1<<1],hd,tl,dis[N1],id[N1],flow[N1],use[N1];
31 int spfa()
32 {
33     int x,j,v;
34     memset(dis,-1,sizeof(dis)); memset(flow,0,sizeof(flow)); memset(use,0,sizeof(use));
35     hd=1,tl=0; que[++tl]=S; dis[S]=0; use[S]=1; flow[S]=inf;
36     while(hd<=tl)
37     {
38         x=que[hd++];
39         for(j=e.head[x];j;j=e.nxt[j])
40         {
41             v=e.to[j];
42             if( e.flow[j]>0 && dis[v]<dis[x]+e.dis[j] )
43             {
44                 dis[v]=dis[x]+e.dis[j]; id[v]=j;
45                 flow[v]=min(flow[x],e.flow[j]);
46                 if(!use[v]) que[++tl]=v, use[v]=1;
47             }
48         }
49         use[x]=0;
50     }
51     return dis[T]!=-1;
52 }
53 int EK()
54 {
55     int tcost=0,mxflow=0,x;
56     while(spfa())
57     {
58         mxflow+=flow[T]; tcost+=flow[T]*dis[T];
59         for(x=T;x!=S;x=e.to[id[x]^1])
60         {
61             e.flow[id[x]]-=flow[T];
62             e.flow[id[x]^1]+=flow[T];
63         }
64     }
65     return tcost;
66 }
67
68 int l[N1],r[N1],p[N1],len[N1],t[N1<<1],cnt;
69 int main()
70 {
71     scanf("%d%d",&n,&K);
72     int i,j,x,y,ma; e.cte=1;
73     for(i=1;i<=n;i++)
74     {
75         l[i]=gint(), x=gint(), r[i]=gint(), y=gint();
76         if(l[i]>r[i]) swap(l[i],r[i]), swap(x,y);
77         len[i]=sqrt( 1ll*(r[i]-l[i])*(r[i]-l[i])+1ll*(y-x)*(y-x) );
78         if(l[i]!=r[i]) r[i]--; else p[i]=1;
79         t[++cnt]=l[i], t[++cnt]=r[i];
80     }
81     sort(t+1,t+cnt+1); cnt=unique(t+1,t+cnt+1)-(t+1);
82     for(i=1;i<=n;i++)
83     {
84         x=lower_bound(t+1,t+cnt+1,l[i])-t;
85         y=lower_bound(t+1,t+cnt+1,r[i])-t;
86         if(p[i]){ l[i]=x*2-1, r[i]=y*2-1; }
87         else{ l[i]=x*2; r[i]=y*2; }
88     }
89     S=0; T=cnt*2+1;
90     for(i=1;i<=n;i++) e.ae(l[i],r[i]+1,1,len[i]), e.ae(r[i]+1,l[i],0,-len[i]);
91     for(i=1;i<=cnt*2;i++) e.ae(i,i+1,K,0), e.ae(i+1,i,0,0); e.ae(S,1,K,0); e.ae(1,S,0,0);
92     printf("%d\n",EK());
93     return 0;
94 }

转载于:https://www.cnblogs.com/guapisolo/p/10291903.html

[网络流24题] 最长k可重线段集问题 (费用流)相关推荐

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

    对于区间 u->v ,连接边 u->v,权值为-len,容量为1,之后对每个点 i->i+1,连边 i->i+1,容量为k,权值为0,求区间最左端点到最右端点的费用流,费用相反 ...

  2. 网络流二十四题 ————(二十一)、P3358 最长k可重区间集问题 费用流并联与串联选择

    https://www.luogu.com.cn/problem/solution/P3358 洛谷大佬们题解写的很棒,我就不献丑了. 说下我的理解吧,可以把这个限制过程当初物理中的电路并联与串联.流 ...

  3. P3357 最长k可重线段集问题(网络流/串联/拆点)

    P3357 最长k可重线段集问题 对于n条开线段,选择一个子集使得任意x=p和子集相交的直线个数小于等于k,并使得选择的线段长度之和最大. 这道题看上去和区间集没有什么区别,只是费用发生变化,但是要注 ...

  4. P3357 最长k可重线段集问题 网络流

    P3357 最长k可重线段集问题 题目描述 给定平面 x-O-yx−O−y 上 nn 个开线段组成的集合 II,和一个正整数 kk .试设计一个算法,从开线段集合 II 中选取出开线段集合 S\sub ...

  5. 洛谷P3357:最长k可重线段集问题(网络流)

    解析 本题的建模方法有很多,我的做法是补集思想转化成志愿者招募然后按照那道题的做法直接做,看题解更多是采用的对于不冲突的线段首尾加边的做法. 在前一道最长k可重区间问题中这两种做法谈不上孰优孰劣,但本 ...

  6. 洛谷 - P3357 最长k可重线段集问题(最大费用最大流+思维建边+拆点)

    题目链接:点击查看 题目大意:给出n条开线段,开线段的意思就是端点的两个点属于开区间,不属于线段中,让从中选出数条线段,满足: 在x轴选取任何一个点,选取线段向x轴映射到该点的次数小于等于k 所选线段 ...

  7. 最长k可重区间集问题最长k可重线段集问题

    题解: 洛谷上这两题的题意都是有问题的 按照标程题意不应该是开区间而是左开右闭区间 然后连边比较巧妙 我们可以看成选k条不相交的路径,其中i-i+1中有k条边 所以建图i-i+1流量为k,权值为0 l ...

  8. 【刷题】LOJ 6014 「网络流 24 题」最长 k 可重区间集

    题目描述 给定实直线 \(L\) 上 \(n\) 个开区间组成的集合 \(I\) ,和一个正整数 \(k\) ,试设计一个算法,从开区间集合 \(I\) 中选取出开区间集合 \(S \subseteq ...

  9. [网络流24题] 最长递增子序列

    [网络流24题] 最长递增子序列 «问题描述: 给定正整数序列x1,..., xn. (1)计算其最长递增子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的递增子序列. (3)如果允 ...

  10. P3358 最长k可重区间集问题(网络流:串联思想)

    P3358 最长k可重区间集问题 这是一个经典模型,给定n个开区间,选择一些区间使得每个位置被覆盖次数不超过k,并最大化选择的区间长度之和. 首先一个直接的想法就是每一个区间匹配了它所对应的点,但是我 ...

最新文章

  1. oracle中怎么导外表,ORACLE 自定义类型该如何导入????
  2. ElasticSearch服务器操作命令
  3. jsp中的java部分_jsp页面的七个组成部分
  4. Java8特性解决空指针问题
  5. Multiple Gift(AtCoder-3731)
  6. 转:SQL:外连接on条件与where条件的区别
  7. 英特尔服务器主板型号参数对照表,intel主板_目前市场上intel主板芯片组型号对应cpu针脚数量?...
  8. 恐怖黎明 联网显示无法连接服务器,豪横的刷刷刷 2021年最值得体验的暗黑类游戏...
  9. win10计算机 需要新应用,win10 计算器提示:需要新应用打开此calculator
  10. Trajan求割边,强连通分量
  11. java 多线程抢票_多线程抢票详解
  12. 高仿闪电报销app查看图片效果的实现
  13. 6000多万铲屎官,捧得出一个国产主粮的春天吗?
  14. SODA Foundation中国区启动仪式在联通沃云峰会(WCS)2019成功举行
  15. 企业微信打卡怎么防止作弊?看看其他企业是怎么做的
  16. pygame中display模块方法详解
  17. 软件测试的方法一共有几种
  18. 小米4可以刷入linux,给小米4刷上SailfishOS是怎样的体验?附刷机教程
  19. 企业宣传720vr全景展示优化网上营销体验
  20. Houdini `@pdg_output`找不到文件

热门文章

  1. python工厂模式看不懂_python模式 工厂模式原理及实例详解
  2. 使用apktool来解包和重新打包
  3. 山西农业大学c语言程序设计试卷答案,2016年宁夏医科大学公共卫生与管理学院C语言程序设计(加试)复试笔试最后押题五套卷...
  4. mysql数据库操作函数_MySQL中几个常用的数据库操作函数
  5. 利用定时器中断方式控制led灯的闪烁速度_实验四 LED点阵
  6. Matlab中的逻辑运算:“any”,“all”
  7. 少样本学习系列(一)【Metrics-Based Methods】
  8. 【浙江大学PAT真题练习乙级】1003 我要通过!(20分) 真题解析
  9. Richard S. Sutton个人主页翻译
  10. ML算法整理(一)线性回归与梯度下降 python实现