解析

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

做法和上一题似乎很像,区别一是权值定义有变,二就是关键的垂直线段处理了。
按照题解的做法,直接特判讨论即可。
如果按照志愿者招募呢?
注意到,一条 x=cx=cx=c 的垂直线段和 (l,c),(c,r)(l,c),(c,r)(l,c),(c,r) 都是不冲突的。
考虑如何表示。
对于不垂直的线段 (l,r)(l,r)(l,r),将其改为 (2l+1,2r)(2l+1,2r)(2l+1,2r)。
对于垂直线段 x=cx=cx=c 将其改为 (2c,2c+1)(2c,2c+1)(2c,2c+1)。
这样,在不破坏原来冲突性质的前提下,很好的实现我们的要求。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=3e5+100;
const int M=1e6+100;
const int inf=1e9;int n,m,k;int s,t,tot;
struct node{int to,nxt,cap;int w;
}p[N];
int fi[N],cnt,cur[N];
inline void addline(int x,int y,int c,int w){p[++cnt]=(node){y,fi[x],c,w};fi[x]=cnt;return;
}
inline void add(int x,int y,int c,int w){addline(x,y,c,w);addline(y,x,0,-w);return;
}int dis[N];
int vis[N];
queue<int>q;
bool spfa(){fill(dis,dis+1+tot,inf);dis[s]=0;q.push(s);vis[s]=1;while(!q.empty()){int now=q.front();q.pop();vis[now]=0;for(int i=cur[now]=fi[now];~i;i=p[i].nxt){int to=p[i].to;if(dis[to]<=dis[now]+p[i].w||!p[i].cap) continue;dis[to]=dis[now]+p[i].w;if(!vis[to]) vis[to]=1,q.push(to);}}return dis[t]<inf;
}
int cost;
int flow;
int dfs(int x,int lim){if(vis[x]) return 0;if(x==t||!lim){cost+=lim*dis[t];return lim;}vis[x]=1;int res(0);for(int &i=cur[x];~i;i=p[i].nxt){int to=p[i].to;if(dis[to]!=dis[x]+p[i].w) continue;int add=dfs(to,min(lim,p[i].cap));res+=add;lim-=add;p[i].cap-=add;p[i^1].cap+=add;if(!lim) break;}if(!res) dis[x]=-1;vis[x]=0;return res;
}
void dinic(){flow=cost=0;int tmp(0);while(spfa()){while((tmp=dfs(s,inf))) flow+=tmp;}return;
}
int que[1050],l[1050],r[1050],sum[1050],num;
int val[1050],ans;
signed main(){#ifndef ONLINE_JUDGE//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);#endifmemset(fi,-1,sizeof(fi));cnt=-1;n=read();k=read();for(int i=1;i<=n;i++){int a=read(),b=read(),c=read(),d=read();if(a>c){swap(a,c);swap(b,d);}        val[i]=floor(sqrt(1ll*(a-c)*(a-c)+1ll*(b-d)*(b-d)));ans+=val[i];a<<=1;c<<=1;if(a==c) c++;else a++;l[i]=a;r[i]=c;que[++num]=l[i];que[++num]=r[i];}sort(que+1,que+1+num);num=unique(que+1,que+1+num)-que-1;tot=num;s=++tot;t=++tot;add(s,1,inf,0);add(num,t,inf,0);for(int i=1;i<=n;i++){l[i]=lower_bound(que+1,que+1+num,l[i])-que;r[i]=lower_bound(que+1,que+1+num,r[i])-que;sum[l[i]]++;sum[r[i]]--;//printf("(%d %d)\n",l[i],r[i]);add(l[i],r[i],1,val[i]);}for(int i=1;i<num;i++){sum[i]+=sum[i-1];int o=max(sum[i]-k,0);//printf("i=%d sum=%d o=%d\n",i,sum[i],o);add(i,i+1,inf-o,0);}dinic();ans-=cost;printf("%d\n",ans);return 0;
}
/*
4 2
2 0 7 4
5 4 8 6
0 5 8 6
3 1 4 6
*/

洛谷P3357:最长k可重线段集问题(网络流)相关推荐

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

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

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

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

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

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

  4. 洛谷 - P3358 最长k可重区间集问题(最大费用最大流+思维建边)

    题目链接:点击查看 题目大意:给出n个开区间,现在要求从中选取一定数量的区间,需要满足: 对于任意点x,所选取的区间中包含点x的个数小于等于k 区间长度和最大 要求输出最长的区间长度和 题目分析:一开 ...

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

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

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

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

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

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

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

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

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

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

最新文章

  1. 接Window服务(二)
  2. 上海Uber优步司机奖励政策(1月18日~1月24日)
  3. 单点登录cas常见问题(四) - ticket有哪些存储方式?
  4. java集群_JAVA架构师学习:实践ZooKeeper 应用场景与集群管理,辛勤总结
  5. Javascript 思维导图
  6. SharePoint 2010: 对于开发人员
  7. Delphi WebBrowser控件的使用
  8. 【流媒體】live555—VS2010 下live555编译、使用及测试
  9. Cache之全相连映射
  10. Mac 麦克风不工作?6 种修复方法
  11. VMware上安装CentOS系统(本人新手,欢迎大家多多指导和关照)
  12. 用OpenStack构建南方电网广东公司能源云
  13. 金蝶 插入重复键值_北京数字化的金蝶财务软件软件-北京金普蝶软件科技有限公司...
  14. 打鱼晒网c语言用switch语句,三天打鱼两天晒网题目的C++源代码.docx
  15. 后缀树系列三:后缀树的应用
  16. linux 关闭系统自动更新,Linux下如何关闭自动更新
  17. 【笔记】Ring-DVFS:基于可靠性感知强化学习的DVFS,适用于实时嵌入式系统
  18. mac系统升级血泪史之根目录创建文件夹问题
  19. 第二十二章 : 格式化输出
  20. 思科CCNA第一本教材 第十一章 配置和测试网络 个人总结

热门文章

  1. 信心满满的去面算法工程师,竟然凉了...
  2. 机器学习:怎样才能做到从入门到不放弃?
  3. 在职场中,长得漂亮真的有用吗?
  4. easyui 修改单元格内容_初学Excel办公软件快速修改文字的方法
  5. java判断时间区间 隔天_Java初中级程序员面试题宝典
  6. python3默认的代码编码是什么-Python3 到底什么是字符编码
  7. linux进程的高级管理,Linux高级程序设计(第2版) PDF扫描版[94MB]
  8. 二分法查找是基于有序_201,查找顺序查找
  9. 归并排序 java 迭代_经典排序算法之归并排序(示例代码)
  10. c++牛客网面试题05. 替换空格