从bzoj2039,3144 小议最小割模型建立法
2017-12-07 13:31
281 查看
bzoj2039
题目分析
我们要以得失平衡的角度来看待最小割模型建立问题。 ——沃兹基朔德人类的第六感告诉我们,这题涉及多人之间的得和失,有可能是一种最小割模型。
根据伟大的文学家沃兹基的话,我们可以知道,最小割模型的一般建立方法是源点流出“得”到每一个点,而每一个点的出边对应每一个选择的“失”,网络流“流走”的过程就相当于你本来得到的东西失去了的过程,所以求最小割,得到的就是你最少要失去多少东西,然后用可得-最少失去=最大获得。
事实上,著名的最大点权独立集问题和最大权闭合子图问题的思想都类似于此。
所以我们把伟大的文学家沃兹基的思想应用到这道题上,建模方法如下:
每个人是一个点。对于点i:
连边(s,i,∑nj=1Ei,j),表示可得。
再连边(i,t,ai)表示选择这个人会失去的。
连边(i,j,Ei,j∗2),表示不选这个人会失去的。会失去的值应该是减去选了这个人后得到的贡献,再减去不选这个人,这个人会干扰j的工作,造成的影响。
最后答案应该是∑ni=1∑nj=1Ei,j-最小割
代码
#include<bits/stdc++.h> using namespace std; #define LL long long const int N=1005,M=2004005;const LL inf=1e14; int n,s,t,tot=1;LL ans; int h ,ne[M],to[M],lev ,q ;LL flow[M]; void add(int x,int y,LL z) { to[++tot]=y,ne[tot]=h[x],h[x]=tot,flow[tot]=z; to[++tot]=x,ne[tot]=h[y],h[y]=tot,flow[tot]=0; } LL dfs(int x,LL liu) { if(x==t) return liu; LL kl,sum=0; for(int i=h[x];i;i=ne[i]) if(lev[to[i]]==lev[x]+1&&flow[i]>0) { kl=dfs(to[i],min(liu-sum,flow[i])); sum+=kl,flow[i]-=kl,flow[i^1]+=kl; if(sum==liu) return sum; } if(!sum) lev[x]=-1; return sum; } int bfs() { for(int i=s;i<=t;++i) lev[i]=0; int x,he=1,ta=1;lev[s]=1,q[1]=s; while(he<=ta) { x=q[he],++he; if(x==t) return 1; for(int i=h[x];i;i=ne[i]) if(!lev[to[i]]&&flow[i]>0) q[++ta]=to[i],lev[to[i]]=lev[x]+1; } return 0; } int main() { LL x; scanf("%d",&n);s=0,t=n+1; for(int i=1;i<=n;++i) scanf("%lld",&x),add(i,t,x); for(int i=1;i<=n;++i) { LL kl=0; for(int j=1;j<=n;++j) { scanf("%lld",&x),kl+=x; if(i!=j) add(i,j,x+x); } add(s,i,kl),ans+=kl; } while(bfs()) ans-=dfs(s,inf); printf("%lld",ans); return 0; }
bzoj3144
题目大意
我们姑且把切糕看成一个由p∗q个高度为r的柱子组成的图形,在每一个竖着的“柱子”上要选择一个点,相邻“柱子”上选择的点高度差不大于d题目分析
选择割边,是选择的一种体现。 ——沃兹基朔德根据伟大文学家沃兹基的话,我们可以用割边作为选择。
首先对于切糕上的每一个点,图中建立一个点,然后建立一个“虚拟”层,相当于把“柱子”增高了。(其实也可以不用建,但这样子比较不容易出错)
首先s向第一层的点都连一条流量为inf的边。
然后最后一层(虚拟层)向汇点连一条流量为inf的边。
然后对于点i,我们把i向与i在同一个“柱子”但是在i下方的点连一条流量为i的不和谐值的边。把这条边割掉,代表选择了这个点。这样我们发现,每一根“柱子”上的点连成了一条链,为了求出最小割,每一条“链条”上都必须有一条边被割掉,相当于在“柱子”上选点。
然后就是限制条件,相邻“柱子”之间的点不能相差d的那个。
也就是说,如果相邻“链条”上选择割掉的那条边代表的点(这条边的起点)与其距离差大于了d,那么此时这根“链条”上依然存在一条可以到达汇点的路径。
也就是连边(id(x1,y1,z1),id(x2,y2,z1−d),inf),这样保证(x2,y2,z1−d)以上的点在(x1,y1,z1)被选择后不会被选择,由于(x2,y2)这根柱子上的点也会这样连边一次,所以在(x1,y1,z1)下面的不能选的点也被考虑了。
答案就是最小割。
代码
#include<bits/stdc++.h> using namespace std; const int N=45*45*45+5,M=3e5+5,inf=0x3f3f3f3f; int P,Q,R,d,s,t,tot=1,ans; int h ,ne[M],to[M],flow[M],q ,lev ,bj[45][45][45]; int mvx[6]={0,1,-1,0,0},mvy[6]={0,0,0,1,-1}; void add(int x,int y,int z) { to[++tot]=y,ne[tot]=h[x],h[x]=tot,flow[tot]=z; to[++tot]=x,ne[tot]=h[y],h[y]=tot,flow[tot]=0; } int dfs(int x,int liu) { if(x==t) return liu; int kl,sum=0; for(int i=h[x];i;i=ne[i]) if(flow[i]>0&&lev[to[i]]==lev[x]+1) { kl=dfs(to[i],min(liu-sum,flow[i])); flow[i]-=kl,flow[i^1]+=kl,sum+=kl; if(sum==liu) return sum; } if(!sum) lev[x]=-1; return sum; } int bfs() { for(int i=s;i<=t;++i) lev[i]=0; int ta=1,he=1,x; q[1]=s,lev[s]=1; while(he<=ta) { x=q[he],++he; if(x==t) return 1; for(int i=h[x];i;i=ne[i]) if(flow[i]>0&&!lev[to[i]]) lev[to[i]]=lev[x]+1,q[++ta]=to[i]; } return 0; } void init() { scanf("%d%d%d%d",&P,&Q,&R,&d); s=0,t=P*Q*(R+1)+1;int cnt=0; for(int i=1;i<=R+1;++i) for(int j=1;j<=P;++j) for(int k=1;k<=Q;++k) bj[i][j][k]=++cnt; } int main() { int x;init(); for(int i=1;i<=R;++i) for(int j=1;j<=P;++j) for(int k=1;k<=Q;++k) scanf("%d",&x),add(bj[i][j][k],bj[i+1][j][k],x); for(int i=1;i<=P;++i) for(int j=1;j<=Q;++j) add(s,bj[1][i][j],inf),add(bj[R+1][i][j],t,inf); for(int x1=1;x1<=P;++x1) for(int y1=1;y1<=Q;++y1) { for(int k=1;k<=4;++k) { int x2=x1+mvx[k],y2=y1+mvy[k]; if(x2<1||x2>P||y2<1||y2>Q) continue; for(int t=d+1;t<=R;++t) add(bj[t][x1][y1],bj[t-d][x2][y2],inf); } } while(bfs()) ans+=dfs(s,inf); printf("%d",ans); return 0; }
相关文章推荐
- 【网络流之最小割模型】poj3469 BZOJ3144 UVA1212
- BZOJ 2039: [2009国家集训队]employ人员雇佣 最小割 二元组建图模型
- 【BZOJ 3144】 3144: [Hnoi2013]切糕 (最小割模型)
- bzoj 2039 最小割模型
- 【网络流之最小割模型】poj3469 BZOJ3144 UVA1212
- bzoj 2039 人员雇佣【最小割】
- 【bzoj2039】[2009国家集训队]employ人员雇佣 最小割
- [Bzoj2039][2009国家集训队]employ人员雇佣(最小割)
- 【BZOJ3144】[Hnoi2013]切糕【最小割】
- BZOJ 2039 最小割
- BZOJ 3144 切糕(最小割)
- BZOJ_2039_[2009国家集训队]employ人员雇佣_ 最小割
- [BZOJ 3144] [Hnoi2013] 切糕 【最小割】
- 【BZOJ 3144】 [Hnoi2013]切糕 真·最小割
- BZOJ 3144: [Hnoi2013]切糕 最小割
- 【bzoj3144】[Hnoi2013]切糕 网络流最小割
- 【BZOJ2039】[2009国家集训队]employ人员雇佣 最小割
- 【BZOJ2039】[2009国家集训队]employ人员雇佣【最小割】
- BZOJ-1095 Hide 捉迷藏 模型建立+线段树
- bzoj 3144: [Hnoi2013]切糕 最小割