BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流
BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流
Description
有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i]]这么多段长度为1时间中选出一个时间进行抢劫,并计划抢走c[i]元。作为保安,你在每一段长度为1的时间内最多只能制止一个强盗,那么你最多可以挽回多少损失呢?Input
第一行包含一个正整数n(1<=n<=5000),表示强盗的个数。 接下来n行,每行包含三个正整数a[i],b[i],c[i](1<=a[i]<b[i]<=5000,1<=c[i]<=10000),依次描述每一个强盗。Output
输出一个整数,即可以挽回的损失的最大值。Sample Input
41 4 40
2 4 10
2 3 30
1 3 20
Sample Output
90
S对每个强盗连边(1,c[i]),每个强盗对所在时间连边(1,0),每个时间对T连边(1,0)。
然后跑最大费用最大流。
这是一个朴素的想法,然后我们发现强盗的时间都是一段连续的区间。
线段树优化建图,结点连向儿子(inf,0),叶子连向T,相当于多开出4n的辅助结点,主要的连边方式不变。
注意每次增广时只会使流量+1,因此不需要找一遍最小的流。
反正我不加这个优化就T了。
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 25050 #define M 200050 #define inf 0x3f3f3f3f int head ,to[M],nxt[M],flow[M],cnt=1,val[M]; int ls ,rs ,tot=2,S=1,T=2,Q ,l,r,inq ,dis ,path ,n,maxl,aa ,bb ,cc ; void add(int u,int v,int f,int c) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f; val[cnt]=c; to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0; val[cnt]=-c; } bool spfa() { memset(dis,0x80,sizeof(dis)); memset(path,0,sizeof(path)); dis[S]=0; l=r=0; Q[r++]=S; while(l!=r) { int x=Q[l++],i; inq[x]=0; if(l==tot+1) l=0; for(i=head[x];i;i=nxt[i]) { if(dis[to[i]]<dis[x]+val[i]&&flow[i]) { dis[to[i]]=dis[x]+val[i]; path[to[i]]=i^1; if(!inq[to[i]]) { inq[to[i]]=1; if(dis[to[i]]>dis[Q[l]]) { l--; if(l==-1) l=tot; Q[l]=to[i]; } else { Q[r++]=to[i]; if(r==tot+1) r=0; } } } } } return path[T]; } void mcmf() { int nf,i,ans=0; while(spfa()) { ans+=dis[T]; for(i=T;i!=S;i=to[path[i]]) { flow[path[i]^1]--; flow[path[i]]++; } } printf("%d\n",ans); } void build(int l,int r,int &p) { p=++tot; if(l==r) {add(p,T,1,0);return ;} int mid=(l+r)>>1; build(l,mid,ls[p]); build(mid+1,r,rs[p]); add(p,ls[p],inf,0); add(p,rs[p],inf,0); } void update(int l,int r,int x,int y,int p) { if(x<=l&&y>=r) { add(tot,p,1,0); return ; } int mid=(l+r)>>1; if(x<=mid) update(l,mid,x,y,ls[p]); if(y>mid) update(mid+1,r,x,y,rs[p]); } int main() { register int i,root=0; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d%d",&aa[i],&bb[i],&cc[i]); bb[i]--; maxl=max(maxl,bb[i]); } build(1,maxl,root); for(i=1;i<=n;i++) { tot++; add(S,tot,1,cc[i]); update(1,maxl,aa[i],bb[i],root); } mcmf(); }
- 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 && BZOJ 2034 [2009国家集训队]最大收益
- 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 线段树优化建图+费用流
- [bzoj4276][ONTAK2015]Bajtman i Okrągły Robin
- BZOJ 4276: [ONTAK2015]Bajtman i Okrągły Robin|贪心|匈牙利
- 4276: [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
- BZOJ 4276: [ONTAK2015]Bajtman i Okrągły Robin [线段树优化建边]
- 【线段树优化建图+费用流】BZOJ4276 [ONTAK2015]Bajtman i Okrągły Robin
- 4276: [ONTAK2015]Bajtman i Okrągły Robin 线段树优化费用流
- 【线段树优化建图+费用流Spfa增广】BZOJ4276(ONTAK2015)[Bajtman i Okrągły Robin]题解
- 4276: [ONTAK2015]Bajtman i Okrągły Robin
- BZOJ4276: [ONTAK2015]Bajtman i Okrągły Robin
- [ONTAK2015]Bajtman i Okrągły Robin