bzoj 4276: [ONTAK2015]Bajtman i Okrągły Robin【线段树+最大费用最大流】
2018-02-11 18:59
381 查看
……因为T点忘记还要+n所以选小了所以WA了一次
注意!题目中所给的时间是一边闭一边开的区间,所以读进来之后先l++(或者r--也行)
线段树优化建图,很神。(我记得还有个主席树优化建树的?)首先考虑暴力建图:s向每个强盗i连(s,i,1,c[i]),每个时间j向t连(j,t,1,0),每个强盗向所有他的时间j连边(i,j,1,0),然而这样显然是会TLE的。
所以考虑向区间连边,建一颗线段树,每个区间向它的两个子节点连费用0流量inf的边,叶节点向t(注意开大!)连费用0流量1的边限制“你在每一段长度为1的时间内最多只能制止一个强盗”,s向所有强盗i连边(s,i,1,0),然后把强盗i的时间区间放在线段树上,从i向每个区间的编号j连(i,j,inf,c[i])。最后跑最大费用最大流即可。
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; const int N=2000005,inf=1e9; int n,h ,cnt=1,dis ,fr ,ans,S,T; bool v ; struct qwe { int ne,no,to,va,c; }e[N<<2]; struct xds { int l,r,sum; }t ; int read() { int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } return r*f; } void add(int u,int v,int w,int c) { cnt++; e[cnt].ne=h[u]; e[cnt].no=u; e[cnt].to=v; e[cnt].va=w; e[cnt].c=c; h[u]=cnt; } void ins(int u,int v,int w,int c) {//cout<<u<<" "<<v<<" "<<w<<endl; add(u,v,w,c); add(v,u,0,-c); } bool spfa() { queue<int>q; for(int i=S;i<=T;i++) dis[i]=-inf; dis[S]=0; v[S]=1; q.push(S); while(!q.empty()) { int u=q.front(); q.pop(); v[u]=0; for(int i=h[u];i;i=e[i].ne) if(e[i].va>0&&dis[e[i].to]<dis[u]+e[i].c) { dis[e[i].to]=dis[u]+e[i].c; fr[e[i].to]=i; if(!v[e[i].to]) { v[e[i].to]=1; q.push(e[i].to); } } } return dis[T]!=-inf; } void mcf() {//cout<<"OK"<<endl; int x=inf; for(int i=fr[T];i;i=fr[e[i].no]) x=min(x,e[i].va); for(int i=fr[T];i;i=fr[e[i].no]) { e[i].va-=x; e[i^1].va+=x; ans+=x*e[i].c; } } void build(int ro,int l,int r) { t[ro].l=l,t[ro].r=r; if(l==r) { ins(ro+n,T,1,0); return; } int mid=(l+r)>>1; ins(ro+n,(ro<<1)+n,inf,0); build(ro<<1,l,mid); ins(ro+n,(ro<<1|1)+n,inf,0); build(ro<<1|1,mid+1,r); } void update(int ro,int l,int r,int w,int i) { if(t[ro].l==l&&t[ro].r==r) { ins(i,ro+n,inf,w); return; } int mid=(t[ro].l+t[ro].r)>>1; if(r<=mid) update(ro<<1,l,r,w,i); else if(l>mid) update(ro<<1|1,l,r,w,i); else { update(ro<<1,l,mid,w,i); update(ro<<1|1,mid+1,r,w,i); } } int main() { n=read(); S=0,T=30000; build(1,1,n); for(int i=1;i<=n;i++) ins(S,i,1,0); for(int i=1;i<=n;i++) { int l=read()+1,r=read(),w=read(); update(1,l,r,w,i); } while(spfa()) mcf(); printf("%d\n",ans); return 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 费用流+线段树优化构图
- [二分图匹配 贪心] 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|贪心|匈牙利
- 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
- 【线段树优化建图+费用流】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】【二分图匹配】
- BZOJ 4276([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