BZOJ 4276 [ONTAK2015]Bajtman i Okrągły Robin 费用流 线段树优化建图
来源:互联网 发布:大数据工程师 年龄要求 编辑:程序博客网 时间:2024/05/18 03:40
题目大意:n(≤5000)个区间(l,r≤5000),每个区间只能选其中的一个点得到vi的价值,每个点最多选1次,求最大价值
容易想到费用流。
暴力建图(不一定
区间加边,可以用线段树优化建图。
线段树上的每个结点表示一个区间,每个区间向子区间连边,表示如果能到这个区间的话就也可以到达子区间。
然后每个区间往线段树结点上表示的区间连边就好了。
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define N 30005#define INF 1000000000using namespace std;struct Edge { int from,to,nxt,cap,cost; Edge() {} Edge(int _from,int _to,int _nxt,int _cap,int _cost): from(_from),to(_to),nxt(_nxt),cap(_cap),cost(_cost) {}}e[N*10];int n,tot=-1,S,T,tot_cost,tot_flow,fir[N],d[N];bool vis[N],inq[N];void Add_Edge(int from,int to,int cap,int cost) { e[++tot]=Edge(from,to,fir[from],cap,cost), fir[from]=tot; e[++tot]=Edge(to,from,fir[to],0,-cost), fir[to]=tot; return ;}bool SPFA() { queue<int> q; for(int i=S;i<=T;++i) d[i]=INF; d[S]=0, q.push(S), inq[S]=true; while(!q.empty()) { int x=q.front(); q.pop(); inq[x]=false; for(int i=fir[x];~i;i=e[i].nxt) { if(!e[i].cap || d[e[i].to]<=d[x]+e[i].cost) continue; d[e[i].to]=d[x]+e[i].cost; if(!inq[e[i].to]) q.push(e[i].to), inq[e[i].to]=true; } } return d[T]!=INF;}int dfs(int x,int now) { if(x==T || !now) { tot_cost+=now*d[T]; return now; } vis[x]=true; int f,flow=0; for(int i=fir[x];~i;i=e[i].nxt) { if(vis[e[i].to] || d[e[i].to]!=d[x]+e[i].cost) continue; f=dfs(e[i].to,min(now,e[i].cap)); if(!f) continue; e[i].cap-=f, e[i^1].cap+=f; now-=f, flow+=f; if(!now) break; } if(!flow) d[x]=INF; return flow;}void Costflow() { tot_cost=tot_flow=0; while(SPFA()) { for(int i=S;i<=T;++i) vis[i]=false; tot_flow+=dfs(S,INF); } return ;}struct Node { Node* ch[2]; int num,l,r; Node() {} Node(int _l,int _r,int _num):l(_l),r(_r),num(_num) { ch[0]=ch[1]=NULL; } void* operator new(size_t) { static Node *C,*mempool; if(mempool==C) mempool=(C=new Node[1<<20])+(1<<20); return C++; }}*root;void init(Node*& o,int l,int r,int num) { o=new Node(l,r,num); if(l==r) { Add_Edge(n+num,T,1,0); return ; } int mid=l+r>>1; init(o->ch[0],l,mid,num<<1), init(o->ch[1],mid+1,r,num<<1|1); Add_Edge(n+num,n+o->ch[0]->num,INF,0), Add_Edge(n+num,n+o->ch[1]->num,INF,0); return ;}void build(Node* o,int l,int r,int ord) { if(o->l==l && o->r==r) { Add_Edge(ord,n+o->num,1,0); return ; } int mid=o->l+o->r>>1; if(r<=mid) build(o->ch[0],l,r,ord); else if(l>mid) build(o->ch[1],l,r,ord); else build(o->ch[0],l,mid,ord), build(o->ch[1],mid+1,r,ord); return ;}int main() { memset(fir,-1,sizeof fir); scanf("%d",&n); T=n*5+1; init(root,1,n,1); for(int i=1,x,y,z;i<=n;++i) { scanf("%d%d%d",&x,&y,&z), --y; Add_Edge(S,i,1,-z); build(root,x,y,i); } Costflow(); printf("%d\n",-tot_cost); return 0;}
阅读全文
0 0
- bzoj 4276: [ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流
- BZOJ 4276 [ONTAK2015]Bajtman i Okrągły Robin 费用流 线段树优化建图
- BZOJ 4276([ONTAK2015]Bajtman i Okrągły Robin-线段树构图费用流)
- 4276: [ONTAK2015]Bajtman i Okrągły Robin 线段树优化费用流
- 4276: [ONTAK2015]Bajtman i Okrągły Robin 费用流+线段树优化建图/贪心
- BZOJ 4276 ONTAK2015 Bajtman i Okrągły Robin 费用流+线段树优化构图
- 【bzoj4276】[ONTAK2015]Bajtman i Okrągły Robin 费用流+线段树优化建图
- 【线段树优化建图+费用流Spfa增广】BZOJ4276(ONTAK2015)[Bajtman i Okrągły Robin]题解
- 【线段树优化建图+费用流】BZOJ4276 [ONTAK2015]Bajtman i Okrągły Robin
- BZOJ 4276: [ONTAK2015]Bajtman i Okrągły Robin|贪心|匈牙利
- [bzoj4276][ONTAK2015]Bajtman i Okrągły Robin
- Bzoj4276 [ONTAK2015]Bajtman i Okrągły Robin
- BZOJ4276: [ONTAK2015]Bajtman i Okrągły Robin
- 【bzoj4276】【ONTAK2015】【Bajtman i Okrągły Robin】【二分图匹配】
- [二分图匹配 贪心] BZOJ 4276 [ONTAK2015]Bajtman i Okrągły Robin && BZOJ 2034 [2009国家集训队]最大收益
- BZOJ 4276 费用流+线段树构图
- bzoj 4977: 跳伞求生 线段树模拟费用流
- bzoj 4383: [POI2015]Pustynia 线段树优化建图
- Determining Oracle memory usage on AIX
- MIME type类型
- ABAP 7.4 新语法-内嵌生命和内表操作
- Diagnosing Oracle memory on HP using GLANCE
- 排序之----冒泡,直接插入,选择排序
- BZOJ 4276 [ONTAK2015]Bajtman i Okrągły Robin 费用流 线段树优化建图
- 商品展示
- 存储过程与执行计划缓存 优秀文章目录
- Java开发中的23种设计模式详解(转)
- java查看主机指定文件最后修改时间
- Spring Boot: 开发web 应用
- ascii unicode utf8到底是啥
- 【翻译】--docker是什么
- java使用Socket连接指定主机