3218: a + b Problem 最小割+主席树优化建图
来源:互联网 发布:ipad开单软件 编辑:程序博客网 时间:2024/05/29 14:14
妈的这题调了我一下午+半晚上= =
首先暴力最小割建图显然。
建边
然后边数我居然以为5000*5000=250w天真的以为压压内存就过了。
然后限制是一个区间,可以想到线段树优化建图。
如果没有区间限制,我们建立权值线段树,然后将
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=5005;const int M=2000005;const int Q=100005;const int inf=1000000007;int a[N],l[N],r[N],root[N],num[N*3],hash[N*3];int next[M],list[M],key[M];int n,cnt=1,tot,ans,size,S,T;int ls[Q],rs[Q],dis[Q],q[Q],cur[Q],head[Q];inline int read(){ int a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f;}inline void insert(int x,int y,int z){ next[++cnt]=head[x]; head[x]=cnt; list[cnt]=y; key[cnt]=z;}inline bool BFS(){ memset(dis,-1,sizeof(dis)); int t=0,w=1,x; q[1]=S; dis[S]=1; while (t<w) { x=q[++t]; for (int i=head[x];i;i=next[i]) if (key[i]&&dis[list[i]]==-1) dis[q[++w]=list[i]]=dis[x]+1; } return dis[T]!=-1;}int find(int x,int flow){ if (x==T) return flow; int w,used=0; for (int i=cur[x];i;i=next[i]) if (key[i]&&dis[list[i]]==dis[x]+1) { w=find(list[i],min(key[i],flow-used)); key[i]-=w; key[i^1]+=w; used+=w; if (key[i]) cur[x]=i; if (used==flow) return used; } if (!used) dis[x]=-1; return used;}inline int dinic(){ int ans=0; while (BFS()) { for (int i=1;i<=T+size;i++) cur[i]=head[i]; ans+=find(S,inf); } return ans;}inline int Find(int x){ int l=1,r=tot; while (l<=r) { int mid=l+r>>1; if (hash[mid]==x) return mid; else if (hash[mid]<x) l=mid+1; else r=mid-1; }}void update(int l,int r,int x,int &y,int val,int v){ y=++size; insert(y,x,inf); insert(x,y,0); ls[y]=ls[x]; rs[y]=rs[x]; if (ls[y]) insert(y,ls[y],inf),insert(ls[y],y,0); if (rs[y]) insert(y,rs[y],inf),insert(rs[y],y,0); if (l==r) { insert(y,v,inf); insert(v,y,0); return; } int mid=l+r>>1; if (val<=mid) { update(l,mid,ls[x],ls[y],val,v); insert(y,ls[y],inf); insert(ls[y],y,0); } else { update(mid+1,r,rs[x],rs[y],val,v); insert(y,rs[y],inf); insert(rs[y],y,0); }}void query(int l,int r,int k,int x,int y,int v){ if (!k) return; if (l==x&&r==y) { insert(v,k,inf); insert(k,v,0); return; } int mid=l+r>>1; if (y<=mid) query(l,mid,ls[k],x,y,v); else if (x>mid) query(mid+1,r,rs[k],x,y,v); else query(l,mid,ls[k],x,mid,v),query(mid+1,r,rs[k],mid+1,y,v);}int main(){// freopen("color.in","r",stdin);// freopen("color.out","w",stdout); n=read(); S=n<<1|1; T=S+1; size=T; for (int i=1;i<=n;i++) { int b,w,p; a[i]=read(); b=read(); w=read(); l[i]=read(); r[i]=read(); p=read(); ans+=b+w; insert(S,i,b); insert(i,S,0); insert(i,T,w); insert(T,i,0); insert(i,i+n,p); insert(i+n,i,0); num[++num[0]]=a[i]; num[++num[0]]=l[i]; num[++num[0]]=r[i]; } sort(num+1,num+num[0]+1); hash[++tot]=num[1]; for (int i=2;i<=num[0];i++) if (num[i]!=num[i-1]) hash[++tot]=num[i]; for (int i=1;i<=n;i++) a[i]=Find(a[i]),l[i]=Find(l[i]),r[i]=Find(r[i]); for (int i=1;i<=n;i++) { query(1,tot,root[i-1],l[i],r[i],i+n); update(1,tot,root[i-1],root[i],a[i],i); } cout << ans-dinic() << endl; return 0;}
0 0
- 3218: a + b Problem 最小割+主席树优化建图
- [主席树优化建图 最小割] BZOJ 3218 a + b Problem
- bzoj 3218: a + b Problem|最小割|主席树
- 【bzoj3218】 a + b Problem 最小割+主席树
- BZOJ3218 UOJ#77 A+B Problem(最小割+主席树)
- BZOJ 3218 a + b Problem 可持久化线段树+最小割
- bzoj 3218: a + b Problem (可持久化线段树+最小割)
- bzoj 3218: a + b Problem 最小割+可持久化线段树
- [BZOJ3218][UOJ#77]A+B Problem(可持久化线段树+最小割)
- BZOJ 3218 a + b Problem 网络流 可持久化线段树优化建图
- UOJ#77 bzoj3218 a + b Problem 可持久化线段树优化建图+网络流
- HDU 4971 A simple brute force problem.(最小割,最大权闭合图)
- hdoj 4971 A simple brute force problem. 【最大权闭合图 --> 最小割】
- HDU 4971 A simple brute force problem.(最小割,最大权闭合图)
- 【最小割】HDU 4971 A simple brute force problem.
- 3218: a + b Problem
- 3218: a + b Problem
- 图的最小割:Graph-cut:Min-Cut Problem
- Android开发之Intent.Action
- unity3d之半透明粒子遮挡问题
- OpenGL教程
- 如何打印一个变量指定部分的字符
- matlab 降维工具
- 3218: a + b Problem 最小割+主席树优化建图
- Jam的计数法
- Python字符串的编码与解码(encode与decode)
- 一.服务器编程框架
- Android中Canvas绘图基础详解(附源码下载)
- c++平台判断
- 全文索引----solr入门
- eclipse 和 android studio 快捷键对比
- java设计模式之装饰模式