BZOJ 3218 a + b Problem 可持久化线段树+最小割
来源:互联网 发布:哪家淘宝店的衣服好看 编辑:程序博客网 时间:2024/05/27 00:28
题目大意:。。。自己看
从源点出发,分别向汇点连两条流量为a和b的边,跑最大流即是a+b。
代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 10#define S 1#define T 2#define INF 0x3f3f3f3fusing namespace std;struct abcd{int to,f,next;}table[100];int head[M],tot=1;void Add(int x,int y,int z){table[++tot].to=y;table[tot].f=z;table[tot].next=head[x];head[x]=tot;}void Link(int x,int y,int z){Add(x,y,z);Add(y,x,0);}namespace Max_Flow{ int dpt[M]; bool BFS() { static int q[M]; int i,r=0,h=0; memset(dpt,-1,sizeof dpt); q[++r]=S;dpt[S]=1; while(r!=h) { int x=q[++h]; for(i=head[x];i;i=table[i].next) if(table[i].f&&!~dpt[table[i].to]) { dpt[table[i].to]=dpt[x]+1; q[++r]=table[i].to; if(table[i].to==T) return true; } } return false; } int Dinic(int x,int flow) { int i,left=flow; if(x==T) return flow; for(i=head[x];i&&left;i=table[i].next) if(table[i].f&&dpt[table[i].to]==dpt[x]+1) { int temp=Dinic(table[i].to,min(left,table[i].f) ); if(!temp) dpt[table[i].to]=-1; left-=temp; table[i].f-=temp; table[i^1].f+=temp; } return flow-left; } }int main(){using namespace Max_Flow;int i,x,ans=0;for(i=1;i<=2;i++)scanf("%d",&x),Link(S,T,x);while( BFS() )ans+=Dinic(S,INF);cout<<ans<<endl;return 0;}
。。。上面那个是开玩笑的
首先考虑朴素一些的做法
将每个点i拆成两个点i和i',i'向i连一条流量为p的边
从S向i连一条流量为w的边 从i向T连一条流量为b的边
如果j选白点i选黑点时i会变得奇♂怪起来的话,就从j到i'连一条流量为INF的边
这样就保证了如果j选择了白色,i就要么选择白色,要么变得奇♂怪
但是这样建图的话,j->i'的边数可以达到O(n^2)
我们可以考虑建一棵权值线段树,从j向相应叶节点连边,从i‘覆盖的区间向i’连边
但是这样做我们无视了j<i这个条件
因此我们将这棵线段树改成可持久化线段树即可
每新建一条链,从旧版本的每个点和点i分别向新建的链上节点连边
然后去上一个版本查询相应区间并连边即可
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 200200#define S 0#define T 200199#define INF 0x3f3f3f3f#define P1(x) ((x)*2-1)#define P2(x) ((x)<<1)using namespace std;int n,m,cnt;long long ans;namespace Max_Flow{struct abcd{int to,f,next;}table[1001001];int head[M],tot=1;int dpt[M];void Add(int x,int y,int z){table[++tot].to=y;table[tot].f=z;table[tot].next=head[x];head[x]=tot;}void Link(int x,int y,int z){Add(x,y,z);Add(y,x,0);}bool BFS(){static int q[M];int i,r=0,h=0;memset(dpt,-1,sizeof dpt);dpt[S]=1;q[++r]=S;while(r!=h){int x=q[++h];for(i=head[x];i;i=table[i].next)if(table[i].f&&!~dpt[table[i].to]){dpt[table[i].to]=dpt[x]+1;q[++r]=table[i].to;if(table[i].to==T)return true;}}return false;}int Dinic(int x,int flow){int i,left=flow;if(x==T) return flow;for(i=head[x];i&&left;i=table[i].next)if(table[i].f&&dpt[table[i].to]==dpt[x]+1){int temp=Dinic(table[i].to,min(left,table[i].f) );left-=temp;table[i].f-=temp;table[i^1].f+=temp;}if(left) dpt[x]=-1;return flow-left;}void DFS(int x){static int v[M];v[x]=1;if(x<=n<<1)printf("%d\n",x+1>>1);for(int i=head[x];i;i=table[i].next)if(table[i].f&&!v[table[i].to])DFS(table[i].to);}void Debug(){static int s[M],t[M];int i;for(i=head[S];i;i=table[i].next)if(table[i].to<=n<<1)s[table[i].to+1>>1]=(table[i].f?-1:1);for(i=head[T];i;i=table[i].next)if(table[i].to<=n<<1)t[table[i].to+1>>1]=(table[i^1].f?-1:1);for(i=1;i<=n;i++)printf("%d %d %d\n",i,s[i],t[i]);puts("--------------------------------------");DFS(S);puts("--------------------------------------");for(i=head[P2(6)];i;i=table[i].next)if(table[i].to==P1(6))cout<<table[i].f<<endl;puts("--------------------------------------");}}struct Segtree{Segtree *ls,*rs;int val,num;void* operator new (size_t,Segtree *_,Segtree *__,int ___){static Segtree mempool[M],*C=mempool;C->ls=_;C->rs=__;C->val=___;C->num=++cnt;return C++;}Segtree* Build_Tree(int x,int y,int pos,int from){using namespace Max_Flow;int mid=x+y>>1;Segtree *re;if(x==y)re=new (0x0,0x0,val+1) Segtree;else if(pos<=mid)re=new (ls->Build_Tree(x,mid,pos,from),rs,val+1) Segtree;elsere=new (ls,rs->Build_Tree(mid+1,y,pos,from),val+1) Segtree;Link(from,re->num,INF);Link(num,re->num,INF);return re;}void Get_Ans(int x,int y,int l,int r,int to){using namespace Max_Flow;int mid=x+y>>1;if(!val) return ;if(x==l&&y==r){Link(num,to,INF);return ;}if(r<=mid) ls->Get_Ans(x,mid,l,r,to);else if(l>mid) rs->Get_Ans(mid+1,y,l,r,to);else ls->Get_Ans(x,mid,l,mid,to),rs->Get_Ans(mid+1,y,mid+1,r,to);}}*tree[5050];int main(){using namespace Max_Flow;int i,a,b,w,l,r,p;cin>>n;cnt=P2(n);tree[0]=new (0x0,0x0,0) Segtree;tree[0]->ls=tree[0]->rs=tree[0];for(i=1;i<=n;i++){scanf("%d%d%d%d%d%d",&a,&b,&w,&l,&r,&p);Link(S,P1(i),w);Link(P1(i),T,b);tree[i]=tree[i-1]->Build_Tree(0,1000000000,a,P1(i) );tree[i-1]->Get_Ans(0,1000000000,l,r,P2(i) );Link(P2(i),P1(i),p);ans+=w+b;}while( BFS() )ans-=Dinic(S,INF);//Debug();cout<<ans<<endl;return 0;}
3 0
- 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 最大流 + 可持久化线段树
- BZOJ 3218|UOJ 77|A + B Problem|最大流|可持久化线段树
- BZOJ 3218 a + b Problem 网络流 可持久化线段树优化建图
- bzoj 3218: a + b Problem|最小割|主席树
- bzoj 3489: A simple rmq problem 可持久化线段树套可持久化线段树
- [主席树优化建图 最小割] BZOJ 3218 a + b Problem
- 【网络流+可持久化线段树】[UOJ#77/BZOJ3218]A+B Problem
- UOJ#77 bzoj3218 a + b Problem 可持久化线段树优化建图+网络流
- BZOJ 2653 可持久化线段树
- 【bzoj3218】 a + b Problem 最小割+主席树
- BZOJ3218 UOJ#77 A+B Problem(最小割+主席树)
- BZOJ 3673 && BZOJ 3674 可持久化线段树
- 3218: a + b Problem 最小割+主席树优化建图
- BZOJ 2588 Count on a tree (COT) 可持久化线段树
- .net实现oracle数据库中获取新插入数据的id的方法
- Python Popen communicate()和wait()使用上的区别
- i2c 可能用到错误
- incompatible pointer types assigning to 'nsmutablearray ' from 'nsarray '
- pylibcurl之https搜索引擎之网络数据抓取小例子,302moved?google搜索引擎不让你抓搜索结果??ok,此文问题通通解决
- BZOJ 3218 a + b Problem 可持久化线段树+最小割
- php实现自动获取生成关键词功能
- 如何获取Android移动终端设备唯一ID
- DTW算法
- 目的:检测出图像中的“对号” 注意:“对号”有可能和边框是连在一起。
- IE6不支持hover解决方法
- 库依赖 与 gcc
- Android 自定义View (三) 圆环交替 等待效果
- css3中单位px,em,rem,vh,vw,vmin,vmax的区别及浏览器支持情况