以根为原点,所有叶子为汇点建立网络。

对于一条边$(x,y,A,B)$,$x$向$y$连边,容量$A$,费用0,再连边,容量$B-A$,费用1。

然后不断增广,直到费用达到$M$为止的最大流即为答案。

考虑用树链剖分+线段树来模拟这个过程:

首先加入所有费用为0的边,每次求出到根距离最小的可增广的叶子,然后求出路径上容量的最小值,将所有边的容量减掉它。

如果减的过程中有边容量变为0,那么将它加入临时数组$q$中。

然后扫描$q$中所有边,如果一条边之前费用为0,那么把它容量设置为$B-A$,然后将子树内费用都加一,否则将它子树内的点都标记为不可增广。

时间复杂度$O(n\log^2n)$。

#include<cstdio>
const int N=10010,M=33000,inf=~0U>>1;
int n,m,i,x,y,A,B,ans,cnt,q[N],mf[M],mc[M],tf[M],tc[M],td[M];
int g[N],v[N],nxt[N],f[N],d[N],wa[N],wb[N],size[N],son[N],top[N],st[N],en[N],dfn,seq[N],S[N];
void dfs(int x){
size[x]=1;son[x]=-1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
d[v[i]]=d[x]+1;dfs(v[i]);size[x]+=size[v[i]];
if(son[x]<0||size[v[i]]>size[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int y){
seq[st[x]=++dfn]=x;top[x]=y;
if(~son[x])dfs2(son[x],y);
for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
en[x]=dfn;
}
inline int min(int a,int b){return a<b?a:b;}
inline void tagf(int x,int y){mf[x]-=y;tf[x]+=y;}
inline void tagc(int x,int y){if(mc[x]<inf)mc[x]+=y;tc[x]+=y;}
inline void tagd(int x){mc[x]=inf;tc[x]=0;td[x]=1;}
inline void pb(int x){
if(tf[x])tagf(x<<1,tf[x]),tagf(x<<1|1,tf[x]),tf[x]=0;
if(tc[x])tagc(x<<1,tc[x]),tagc(x<<1|1,tc[x]),tc[x]=0;
if(td[x])tagd(x<<1),tagd(x<<1|1),td[x]=0;
}
inline void up(int x){
mf[x]=min(mf[x<<1],mf[x<<1|1]);
mc[x]=min(mc[x<<1],mc[x<<1|1]);
}
void build(int x,int a,int b){
if(a==b){
int y=seq[a];
mf[x]=wa[y];
if(size[y]>1)mc[x]=inf;
return;
}
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b),up(x);
}
void modifyf(int x,int a,int b,int c,int p){
if(a==b){mf[x]=p;return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)modifyf(x<<1,a,mid,c,p);else modifyf(x<<1|1,mid+1,b,c,p);
up(x);
}
void changef(int x,int a,int b,int c,int d,int p){
if(c<=a&&b<=d&&mf[x]>p){tagf(x,p);return;}
if(a==b){
q[++cnt]=seq[a];
mf[x]=0;
return;
}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)changef(x<<1,a,mid,c,d,p);
if(d>mid)changef(x<<1|1,mid+1,b,c,d,p);
up(x);
}
void changec(int x,int a,int b,int c,int d){
if(c<=a&&b<=d){tagc(x,1);return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)changec(x<<1,a,mid,c,d);
if(d>mid)changec(x<<1|1,mid+1,b,c,d);
up(x);
}
void changed(int x,int a,int b,int c,int d){
if(c<=a&&b<=d){tagd(x);return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)changed(x<<1,a,mid,c,d);
if(d>mid)changed(x<<1|1,mid+1,b,c,d);
up(x);
}
int askmf(int x,int a,int b,int c,int d){
if(c<=a&&b<=d)return mf[x];
pb(x);
int mid=(a+b)>>1,t=inf;
if(c<=mid)t=askmf(x<<1,a,mid,c,d);
if(d>mid)t=min(t,askmf(x<<1|1,mid+1,b,c,d));
return up(x),t;
}
inline int getmc(){
int x=1,a=2,b=dfn,mid;
while(a<b){
mid=(a+b)>>1;
if(mc[x<<1]<mc[x<<1|1])x<<=1,b=mid;else x=x<<1|1,a=mid+1;
}
return seq[a];
}
inline int getmf(int x){
int t=inf;
while(top[x])t=min(t,askmf(1,2,dfn,st[top[x]],st[x])),x=f[top[x]];
if(st[x]>=2)t=min(t,askmf(1,2,dfn,2,st[x]));
return t;
}
inline void chain(int x,int y){
cnt=0;
while(top[x])changef(1,2,dfn,st[top[x]],st[x],y),x=f[top[x]];
if(st[x]>=2)changef(1,2,dfn,2,st[x],y);
while(cnt){
x=q[cnt--];
if(!S[x]&&wb[x]>wa[x])modifyf(1,2,dfn,st[x],wb[x]-wa[x]),changec(1,2,dfn,st[x],en[x]);
else changed(1,2,dfn,st[x],en[x]);
S[x]++;
}
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d%d%d%d",&x,&y,&A,&B);
v[i]=y,nxt[i]=g[x],g[x]=i;
f[y]=x,wa[y]=A,wb[y]=B;
}
dfs(0),dfs2(0,0),build(1,2,dfn);
while(mc[1]<inf){
y=getmf(x=getmc());
if(mc[1]*y>m)y=m/mc[1];
if(!y)break;
m-=mc[1]*y;
ans+=y;
chain(x,y);
}
return printf("%d",ans),0;
}

  

BZOJ2040 : [2009国家集训队]拯救Protoss的故乡的更多相关文章

  1. BZOJ2040[2009国家集训队]拯救Protoss的故乡——模拟费用流+线段树+树链剖分

    题目描述 在星历2012年,星灵英雄Zeratul预测到他所在的Aiur行星在M天后会发生持续性暴雨灾害,尤其是他们的首都.而Zeratul作为星灵族的英雄,当然是要尽自己最大的努力帮助星灵族渡过这场 ...

  2. BZOJ 2039: [2009国家集训队]employ人员雇佣

    2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1369  Solved: 667[Submit ...

  3. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7687  Solved: 3516[Subm ...

  4. BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7676  Solved: 3509[Subm ...

  5. 莫队算法 2038: [2009国家集训队]小Z的袜子(hose)

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 ...

  6. BZOJ 2038 [2009国家集训队]小Z的袜子 莫队

    2038: [2009国家集训队]小Z的袜子(hose) 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Descriptionw ...

  7. Bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队,分块,暴力

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 5763  Solved: 2660[Subm ...

  8. BZOJ2038: [2009国家集训队]小Z的袜子(hose) -- 莫队算法 ,,分块

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 3577  Solved: 1652[Subm ...

  9. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) ( 莫队 )

    莫队..先按sqrt(n)分块, 然后按块的顺序对询问排序, 同块就按右端点排序. 然后就按排序后的顺序暴力求解即可. 时间复杂度O(n1.5) --------------------------- ...

随机推荐

  1. 柔性数组 data[0]

    struct MyData {    int nLen;    char data[0];}; 在结构中,data是一个数组名:但该数组没有元素:该数组的真实地址紧随结构体MyData之后,而这个地址 ...

  2. React Native官方DEMO

    官方给我们提供了UIExplorer项目,这里边包含React Native的基本所有组件的使用介绍和方法. 运行官方DEMO步骤如下 安装react native环境 React Native项目源 ...

  3. 红外解码编码学习----verilog

    在设计中运用红外遥控器可以很好的解决按键缺少的问题,还可以方便的控制产品. 红外发射部分: 红外发射管: 判断红外发射管的好坏 : 电路原理图: 接收部分: 传输的NEC协议: 本实验电路: veri ...

  4. AJAX XML返回类型

    例题 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...

  5. 数据库支持emoji表情

    从MySQL5.5.3开始,MySQL 支持一种utf8mb4的字符集,这个字符集能够支持4字节的UTF8编码的字符.utf8mb4字符集能够完美地兼容utf8字符串.在数据存储方面,当一个普通中文字 ...

  6. 怎么把MVC的Controller拆分写到别的类库

    以为很难…… 其实直接继承Controller 并且按MVC_Controllser规则命名. 然后网站项目引用该项目即可.

  7. Pyqt 中__init__(self,parent==None) parent理解

    参考: 在PyQt中,所有class都是从QObject派生而来,QWidget对象就可以有一个parent.这种parent-child关系主要用于两个方面: 没有parent的QWidget类被认 ...

  8. Jquery 自定义弹窗等待

    (function ($) { $.extend({ //弹窗蒙层 ShowLoadDialog : function () { ) { var cusrtxt = $("<div i ...

  9. penghui_031413 Bat命令学习

    penghui_031413   Bat命令学习 基础部分:====================================================================== ...

  10. SSIS Dataflow使用存储过程不能检索列名

    在项目中遇到一个问题,需要在Dataflow中调用一个存储过程,然后把结果生成一个csv文件. 然而在dataflow调用存储过程中遇到了问题,SP不能正确的返回列名. 在SSMT里面明明是可以查出数 ...