博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 3680 Intervals
阅读量:6278 次
发布时间:2019-06-22

本文共 2120 字,大约阅读时间需要 7 分钟。

POJ 3680 Intervals

题目大意:给定一些开区间\((a_i,b_i)\),以及区间的价值\(w_i\)。每个点最多被\(k\)个区间覆盖,要求最大化选取的区间的价值和。

非常神奇的费用流。

我们首先将点离散化,假设有\(m\)个点。然后建立超级源\(S\)和超级汇\(T\)

首先连两条边\((S,1,k,0),(m,T,k,0)\),然后相邻两点之间连边\((i,i+1,k,0)\)。然后对于区间\((a,b)\),我们连\((a,b,1,-w)\)。求出最小费用流后取反。

要想搞懂这神奇的建边方式就要先搞懂它是如何满足“每个点最多被\(k\)个区间覆盖”这一限制的。在一个网络中,流入点\(i\)的流量\(flow\)就是\(i\)还可以被覆盖的次数,或者说\(i\)在之前被覆盖了\(k-flow\)次。当我们选择了区间\((a,b)\)后,\((a,b)\)这些节点的剩余流量都减少了,于是我们连\((a,b,1,-w)\),将这部分流量分流出去。

这种带反悔的最优化问题就可以用费用流来高效解决。

代码:

#include
#include
#include
#include
#include
#define ll long long#define N 405using namespace std;inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}int n,k;int cas;struct interval { int x,y,w;}e[N];int d[N<<1];struct load { int to,next; int flow,c;}s[N<<2];int h[N],cnt;int S,T;void add(int i,int j,int flow,int c) { s[++cnt]=(load) {j,h[i],flow,c};h[i]=cnt; s[++cnt]=(load) {i,h[j],0,-c};h[j]=cnt;}int dis[N];queue
q;bool in[N];int fr[N],edge[N];int ans;bool spfa() { memset(dis,0x3f,sizeof(dis)); dis[0]=0; q.push(0); while(!q.empty()) { int v=q.front();q.pop(); in[v]=0; for(int i=h[v];i;i=s[i].next) { int to=s[i].to; if(s[i].flow&&dis[to]>dis[v]+s[i].c) { dis[to]=dis[v]+s[i].c; fr[to]=v; edge[to]=i; if(!in[to]) { in[to]=1; q.push(to); } } } } if(dis[T]>1e9) return 0; int mn=1e9; for(int i=T;i;i=fr[i]) mn=min(mn,s[edge[i]].flow); for(int i=T;i;i=fr[i]) s[edge[i]].flow-=mn,s[edge[i]^1].flow+=mn; ans+=mn*dis[T]; return 1;}int main() { cas=Get(); while(cas--) { d[0]=0; n=Get(),k=Get(); for(int i=1;i<=n;i++) { int a=Get(),b=Get(),c=Get(); e[i]=(interval) {a,b,c}; d[++d[0]]=a; d[++d[0]]=b; } sort(d+1,d+1+d[0]); int cc=unique(d+1,d+1+d[0])-d; for(int i=1;i<=n;i++) { e[i].x=lower_bound(d+1,d+cc,e[i].x)-d; e[i].y=lower_bound(d+1,d+cc,e[i].y)-d; } T=cc; memset(h,0,sizeof(h)); cnt=1; add(S,1,k,0),add(T-1,T,k,0); for(int i=1;i

转载于:https://www.cnblogs.com/hchhch233/p/10073185.html

你可能感兴趣的文章
VC++中关于TCHAR,WCHAR,LPSTR,LPWSTR,LPCTSTR的解释[转载]
查看>>
一篇文章学会页面传值的10种方法(上)
查看>>
ToDictionary
查看>>
贪心 --- 排序 + 贪心
查看>>
eclipse安装nodejs插件
查看>>
k8s重要概念及部署k8s集群(一)--技术流ken
查看>>
ios中设置收到消息推送时,前后台自定义声音或音乐
查看>>
课堂动手动脑
查看>>
UVA 12232 Exclusive-OR(并查集+思想)
查看>>
thinkphp5--控制器
查看>>
列表的创建、索引、运算、赋值、切片,及一个名字管理列表系统 元组的简介...
查看>>
重装Windows7后装Grub进入Ubuntu
查看>>
OnClickListener结合switch/case的两种方法
查看>>
20172328《程序设计与数据结构》第六周学习总结
查看>>
HashCode和equal方法的理解
查看>>
php多文件上传
查看>>
MVC中FileResult 返回类型返回Excel
查看>>
热情不减!七款Swift应用开源项目推荐
查看>>
“按位或”运算符
查看>>
pl/sql
查看>>