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

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

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

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

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

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

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

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

  1. #include<cstdio>
  2. const int N=10010,M=33000,inf=~0U>>1;
  3. int n,m,i,x,y,A,B,ans,cnt,q[N],mf[M],mc[M],tf[M],tc[M],td[M];
  4. 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];
  5. void dfs(int x){
  6. size[x]=1;son[x]=-1;
  7. for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
  8. d[v[i]]=d[x]+1;dfs(v[i]);size[x]+=size[v[i]];
  9. if(son[x]<0||size[v[i]]>size[son[x]])son[x]=v[i];
  10. }
  11. }
  12. void dfs2(int x,int y){
  13. seq[st[x]=++dfn]=x;top[x]=y;
  14. if(~son[x])dfs2(son[x],y);
  15. for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
  16. en[x]=dfn;
  17. }
  18. inline int min(int a,int b){return a<b?a:b;}
  19. inline void tagf(int x,int y){mf[x]-=y;tf[x]+=y;}
  20. inline void tagc(int x,int y){if(mc[x]<inf)mc[x]+=y;tc[x]+=y;}
  21. inline void tagd(int x){mc[x]=inf;tc[x]=0;td[x]=1;}
  22. inline void pb(int x){
  23. if(tf[x])tagf(x<<1,tf[x]),tagf(x<<1|1,tf[x]),tf[x]=0;
  24. if(tc[x])tagc(x<<1,tc[x]),tagc(x<<1|1,tc[x]),tc[x]=0;
  25. if(td[x])tagd(x<<1),tagd(x<<1|1),td[x]=0;
  26. }
  27. inline void up(int x){
  28. mf[x]=min(mf[x<<1],mf[x<<1|1]);
  29. mc[x]=min(mc[x<<1],mc[x<<1|1]);
  30. }
  31. void build(int x,int a,int b){
  32. if(a==b){
  33. int y=seq[a];
  34. mf[x]=wa[y];
  35. if(size[y]>1)mc[x]=inf;
  36. return;
  37. }
  38. int mid=(a+b)>>1;
  39. build(x<<1,a,mid),build(x<<1|1,mid+1,b),up(x);
  40. }
  41. void modifyf(int x,int a,int b,int c,int p){
  42. if(a==b){mf[x]=p;return;}
  43. pb(x);
  44. int mid=(a+b)>>1;
  45. if(c<=mid)modifyf(x<<1,a,mid,c,p);else modifyf(x<<1|1,mid+1,b,c,p);
  46. up(x);
  47. }
  48. void changef(int x,int a,int b,int c,int d,int p){
  49. if(c<=a&&b<=d&&mf[x]>p){tagf(x,p);return;}
  50. if(a==b){
  51. q[++cnt]=seq[a];
  52. mf[x]=0;
  53. return;
  54. }
  55. pb(x);
  56. int mid=(a+b)>>1;
  57. if(c<=mid)changef(x<<1,a,mid,c,d,p);
  58. if(d>mid)changef(x<<1|1,mid+1,b,c,d,p);
  59. up(x);
  60. }
  61. void changec(int x,int a,int b,int c,int d){
  62. if(c<=a&&b<=d){tagc(x,1);return;}
  63. pb(x);
  64. int mid=(a+b)>>1;
  65. if(c<=mid)changec(x<<1,a,mid,c,d);
  66. if(d>mid)changec(x<<1|1,mid+1,b,c,d);
  67. up(x);
  68. }
  69. void changed(int x,int a,int b,int c,int d){
  70. if(c<=a&&b<=d){tagd(x);return;}
  71. pb(x);
  72. int mid=(a+b)>>1;
  73. if(c<=mid)changed(x<<1,a,mid,c,d);
  74. if(d>mid)changed(x<<1|1,mid+1,b,c,d);
  75. up(x);
  76. }
  77. int askmf(int x,int a,int b,int c,int d){
  78. if(c<=a&&b<=d)return mf[x];
  79. pb(x);
  80. int mid=(a+b)>>1,t=inf;
  81. if(c<=mid)t=askmf(x<<1,a,mid,c,d);
  82. if(d>mid)t=min(t,askmf(x<<1|1,mid+1,b,c,d));
  83. return up(x),t;
  84. }
  85. inline int getmc(){
  86. int x=1,a=2,b=dfn,mid;
  87. while(a<b){
  88. mid=(a+b)>>1;
  89. if(mc[x<<1]<mc[x<<1|1])x<<=1,b=mid;else x=x<<1|1,a=mid+1;
  90. }
  91. return seq[a];
  92. }
  93. inline int getmf(int x){
  94. int t=inf;
  95. while(top[x])t=min(t,askmf(1,2,dfn,st[top[x]],st[x])),x=f[top[x]];
  96. if(st[x]>=2)t=min(t,askmf(1,2,dfn,2,st[x]));
  97. return t;
  98. }
  99. inline void chain(int x,int y){
  100. cnt=0;
  101. while(top[x])changef(1,2,dfn,st[top[x]],st[x],y),x=f[top[x]];
  102. if(st[x]>=2)changef(1,2,dfn,2,st[x],y);
  103. while(cnt){
  104. x=q[cnt--];
  105. 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]);
  106. else changed(1,2,dfn,st[x],en[x]);
  107. S[x]++;
  108. }
  109. }
  110. int main(){
  111. scanf("%d%d",&n,&m);
  112. for(i=1;i<=n;i++){
  113. scanf("%d%d%d%d",&x,&y,&A,&B);
  114. v[i]=y,nxt[i]=g[x],g[x]=i;
  115. f[y]=x,wa[y]=A,wb[y]=B;
  116. }
  117. dfs(0),dfs2(0,0),build(1,2,dfn);
  118. while(mc[1]<inf){
  119. y=getmf(x=getmc());
  120. if(mc[1]*y>m)y=m/mc[1];
  121. if(!y)break;
  122. m-=mc[1]*y;
  123. ans+=y;
  124. chain(x,y);
  125. }
  126. return printf("%d",ans),0;
  127. }

  

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. viewpager中彻底性动态添加、删除Fragment

    为了解决彻底删除fragment,我们要做的是:1.将FragmentPagerAdapter 替换成FragmentStatePagerAdapter,因为前者只要加载过,fragment中的视图就 ...

  2. 浅析 - 提高xib(Interface Builder)高效工作的几个小技巧

    本文译自:8 Tips for working effectively with Interface Builder(需FQ)先来看看目录:介绍使view的Size与view中的Content相适应按 ...

  3. Page Object Model (Selenium, Python)

    时间 2015-06-15 00:11:56  Qxf2 blog 原文  http://qxf2.com/blog/page-object-model-selenium-python/ 主题 Sel ...

  4. tableView 局部刷新

    //一个section刷新 NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:2]; [tableview reloadSections:in ...

  5. 【PHP对XML文件的操作技术【完整版】】

    无论是c/c++还是java.c#均有对XML文件操作的技术,PHP对XML文件的操作的技术主要有三种: DOM.XPath.SimpleXml. 一.DOM DOM:Document Object ...

  6. 攻城狮在路上(肆)How tomcat works(一) 简单的web服务器

     该节总共三个类:Request\Response\HttpServer---user.dir     该节的目的是实现简单web服务器对静态文件的访问.需要对请求头.请求体的格式有所了解,不然就没有 ...

  7. memcache(使用php操作memcache)

    .概念 memcache 是一个高效的分布式的内存对象缓存系统,他可以支持把php的各种数据(数组,对象,基本数据类型)放在它管理的内存中 . 安装步骤 1.下载php_memcache.dll文件并 ...

  8. jQuery.fn.extend与jQuery.extend到底区别在哪?

    正文: 其实说白了,从两个方法本身就能看出来端倪. 我们先把jQuery看成了一个类,这样好理解一些. jQuery.extend(),是扩展的jQuery这个类. 假设我们把jQuery这个类看成是 ...

  9. WPF标准控件模板查看程序(文件里面)

    xaml <Window x:Class="ControlTemplateBrowser.MainWindow" xmlns="http://schemas.mic ...

  10. XML 文件解析

    1.XML文件 <Data> <Movie id="1"> <title>good lucky to you</title> < ...