有上下界的网络流学习笔记 – liu_runda

实则次要是为了本身的搁置起来。

授予讲师可以纯熟地玩炮底架。

有上下界的广播网流的磁心是”调节器”,we的自己人格形式经过单独未必F的初始流量来调节器单独切实可行的的流量。,最大/最小流量也可以从切实可行的的调节器,而不是下令的。

另类的经用手法是源汇和顺从汇流(圆流)的替换要不是顺从吸光度切实可行的流的求解,另一边起作用的汇的上下界广播网流都要用到这人手法.

  1. 被动的汇有上下界切实可行的流(更确切地说,圆行程)

训练:单独广播网,找到条浜,去每个慢慢向前移动的行程必要的是>李。<=Hi,每个点必要的清偿过的总流入量=总卸船量(流量避免浪费)(这人流的特点是圆往复,无始无终).

这人算法是有上下界广播网流算法的根底,提供we的自己人格形式对算法受胎深刻的听说,另一边算法,去,我进攻在大坯中解说该算法的思惟和详述。

切实可行的流算法的磁心是将单独使不清偿过的流量避免浪费的初始流调节器成清偿过的流量避免浪费的流.

流量避免浪费,更确切地说,每个点的总流入量=总卸船量。

免得有切实可行的的工艺过程,这么必然清偿过的每条边的流量都大于本利积和流量的下限.因而we的自己人格形式可以令每条边的流量本利积和流量下限,获取初始流量。,于是建出这人流的残量广播网.(即:每条边的流量本利积和这条边的流量下限与流量下限之差)这人初始流未必清偿过的流量避免浪费,去终极的切实可行的流必然是在这人初始流的根底上增大了大约边的流量使得所稍许的清偿过的流量避免浪费.

去,we的自己人格形式思索单独不安分的的盈余流量。,于是使附加流与we的自己人格形式的初始流合以清偿过的C

免得某个点在自己人边流量本利积和下界的初始流中清偿过的流量避免浪费,这点也清偿过的了附加流中间的行程避免浪费。,

免得单独点比初始流中间的卸船有更多的流入,则,这点在附加流中间的卸船量大于

免得单独点在初始流中流入不足卸船,x,去,这点在附加流中间的卸船量不足

         可以以为附加流中条从u到v的副的的单独流量代表将原图中u到v的流量增大1

x的数值可以细目x的自己人边,更附近的。,A[i]训令I在初始行程中间的流入卸船。,A[I]的正和负表现流入中间的相干。,接下来,we的自己人格形式运用单独[I]表现I在初始FLO中间的流入和卸船。

依然,DIIC算法可以找到柔韧的宿SA的最大流。,不克不及在原广播网上直率的求单独这样的事物的被动的汇且使不清偿过的流量避免浪费的附加流.注意到附加流是在原广播网上使不清偿过的流量避免浪费的,这激起了we的自己人格形式在原始广播网那一边添加大约慢慢向前移动和点。,这些边和点用于引起交通流的限度局限。

详细地,免得单独点i在原广播网上的附加流中必要清偿过的流入量>卸船量(初始流中流入量<卸船量,A[i]<0),这么we的自己人格形式必要给多的流入量找单独去处,因而we的自己人格形式开发单独i动身行程的慢慢向前移动= -a[i]。免得[i]>0,更确切地说,we的自己人格形式必要在附加流>流入中卸船。,we的自己人格形式必要让更多的资产卸船。,因而we的自己人格形式开发取向i行程的慢慢向前移动= a[i]

自然,we的自己人格形式也必要有单独参加来重行开端。,缺少活力的一种办法可以指导我的慢慢向前移动。,因而we的自己人格形式新建单独制作样本源点ss和单独制作样本汇点tt(双写字母是为了和起作用的汇广播网流中间的源点s汇点t相区别).新建的指导i的边都从ss动身,从我的边指导单独点TT。或任何人到TT。,任何任何人都由于SS。,

TT慢慢向前移动总流量的下限必要的本利积和UPP的下限。,由于每个边都有两个正和负A[I]相当的奉献,去,所稍许的A[i]的和本利积和0。,更确切地说,不足0的总和的有无上权力或权威的=有无上权力或权威的O。

免得we的自己人格形式能找到清偿过的新添加剂的流,则边是满的。,编造流的切断是we的自己人格形式必要的附加流。,“新加的边都满流”和”附加流合上初始流记下流量抵消的流”是均等的约束条件).

这么we的自己人格形式怎样才能找到条丰富行程的慢慢向前移动的新工艺过程呢?we的自己人格形式可以看一眼如果,这样的事物的流必要的是we的自己人格形式建筑的的图的SS TT最大流。,因而跑ss到tt的最大流那就够了.免得最大流的大量本利积和ss动身的自己人边的流量下限积和(此刻指导tt的边也必然满流,由于这两切断边的流量下限积和相当).

极限的,每条边在切实可行的流中间的流量=卷下界+附加流中它的流量(即跑完dinic以前所加反向边的权值).

信号(ZOJ2314 Reactor 冷却的)

#include
#include
#include
usingnamespace std;
constint maxn=300,maxm=100000;
struct edge{
  int to,next,w,num;
LST[MACM]int len=0,first[maxn],_first[maxn];
void addedge(int a,int b,int w,int 努姆)
  LST=num;
  LST=b;LSE].next=first[a];LSE].w=w;first[a]=len++;
  LST=num;
  LST=a;LSE].next=first[b];LSE].w=0高音的[B]=Le;
}
int vis[maxn],dis[maxn],q[maxn],head,tail,s,t,T;
bool bfs(){
  VIS[S]=++T;dis[s]=1;head=tail=0Q [尾]s;
  while(头)!=搭上)
    int x=q[head++];
    for(int Pt=高音的[X];Pt!=-1;pt=LST [ Pt]。下一步)
      if(LST [Pt] W&&VIS[LST[Pt] to)!=T){
    Vist[LST[Pt] to ]DIS[LST[Pt] to ]=DIS[X]1Q [尾]LST [Pt]
      }
    }
  }
  if(V[t]=t),first,sizeof(一)
  return VIS[T]T;
}
int dfs(int x,int 林)
  if(x==t){
    return lim;
  }
  int flow=0,a;
  for(int Pt=高音的[X];Pt!=-1;pt=LST [ Pt]。下一步)
    高音的[ X ]=pt;
    if(LST〔Pt〕W&&dis[lst[pt].to]==dis[x]+1(a=DFS(LST [Pt])。,min(LST[Pt]),lim-工艺过程)
      LST〔Pt〕Wa;1].w+=a;flow+=a;
      if(flow==lim)return flow;
    }
  }
  return flow;
}
int dinic(){
  int ans=0,x;
  while(BFS)
    while(x=dfs(s,0x7f7f7f7f))ans+=x;
  return ans;
}
int 低[记号斯],ANS[MACM]
int totflow[maxn],n,m;

void work(){
  memset(totflow,0,sizeof(totflow));
  memset(first,-1,sizeof(一)len=0;
  scanf("%d%d",&n,&m);
  int u,v,b;
  s=0;t=n+1;
  for(int i=1;i<=m;++i){
    scanf("%d%d%d%d",&u,&v,低[我],&b);
    addedge(u,v,b低[我],Ti流[U]=低[I];TutFLU[V]低[我]
  }
  int sum=0;
  for(int i=1;i<=n;++i){
    if(totflow[i]<0){
      addedge(i,t,-totflow[i],0);
    }else{
      sum+=totf低[我]
      addedge(s,i,totflow[i],0);
    }
  }
  if(第尼克)和)
    puts("YES");
    for(int i=1;i<=n;++i){
      for(int Pt=高音的[i];Pt!=-1;pt=LST [ Pt]。下一步)
    if(LST [Pt] num0||pt%2==0)continue;
    ANS[LST[Pt]·num ]=LST〔Pt〕W+低[LST[Pt]·num ]
      }
    }
    for(int i=1;i<=m;++i)printf("%d\n",ANS[I]
  }else puts("NO");
}
int main(){
  int 实验"%d",&测量法)
  while(测量法)){
    work();if(测量法)油印输入"\n");
  }
  return0;
}

  2. 起作用的汇有上下界切实可行的流

训练:广播网如今有单独。源点s宽恕点T,找到条浜使得源点的总卸船量本利积和汇点的总流入量,另一边点清偿过的行程避免浪费。,并且每条边的流量清偿过的上限和下界限度局限.

源和汇使不清偿过的流量避免浪费。,这使we的自己人格形式很难做到这点。,因而we的自己人格形式想办法把成绩转变成轻易处置的每个点都清偿过的流量避免浪费的被动的汇境况.

为了使源汇清偿过的流量避免浪费,we的自己人格形式必要有慢慢向前移动流入点S。,T.曾经注意到S的卸船本利积和T的流入。,we的自己人格形式就可以从汇点t向源点s连条下界为0上限为无量大的边,相当于把从源点s卸船的流量再流送还.在这样的事物的图中套用上面的算法求出单独切实可行的的圆流,经过将T从汇点移除到源点S,单独切实可行的的Act

这时有单独小成绩:积极的CON的终极切实可行的流量是多少?

可以找到,在圆流中必要的清偿过的S卸船的总流量。,授予原始图中缺少边流入S。,S卸船的行程是从T到S的无限的边流。,即s-t切实可行的流的流量.因而we的自己人格形式极限的看一下t到s的无量边的流量(即dinic跑完以前反向边的权值)那就够了意识到原图中起作用的汇切实可行的流的流量.

信号:这人切实可行的流算法在起作用的汇有上下界最大流/最小流中首都用到,你可以钞票上面两个算法的信号。

3.起作用的汇有上下界最大流

训练:广播网如今有单独。源点s宽恕点T,找到条浜使得源点的总卸船量本利积和汇点的总流入量,另一边点清偿过的行程避免浪费。,并且每条边的流量清偿过的上限和下界限度局限.在这些作出前提下要价总流量达到最大值.

率先套用上面的算法求出单独起作用的汇有上下界切实可行的流.此刻的流未必最大.

接下来,在盈余广播网上运转S-最大流。

终极的最大流流量=切实可行的流流量(即t到s的无量副的跑出的流量)+新增广出的s-t流量

成绩:当些许边使不清偿过的TR的下限时,它会放吗?

不能的.由于we的自己人格形式一开端建的图执意把大量本利积和流量下限的流量拿出去以前的残量广播网,密谋中间的交通毫不。

信号:ZOJ 3229 Shoot The Bullet 东方文花帖 (由于ZoJ的评价可插件如同挂起了。,我不意识到我如果完完全全地。,请仔细。

#include
#include
#include
usingnamespace std;
constint maxn=2005,maxm=100005;
constint inf=0x7f7f7f7f;
struct edge{
  int to,next,w,num;
LST[MACM]int len=0,first[maxn],_first[maxn];
void addedge(int a,int b,int w,int 努姆)
  LST=num;
  LST=b;LSE].next=first[a];LSE].w=w;first[a]=len++;
  LST=num;
  LST=a;LSE].next=first[b];LSE].w=0高音的[B]=Le;
}
int q[maxn],vis[maxn],dis[maxn],T,s,t,head,tail,ss,tt;
bool bfs(){
  head=tail=0;VIS[S]=++TQ [尾]s;
  while(头)!=搭上)
    int x=q[head++];
    for(int Pt=高音的[X];Pt!=-1;pt=LST [ Pt]。下一步)
      if(LST [Pt] W&&VIS[LST[Pt] to)!=T){
    Vist[LST[Pt] to ]DIS[LST[Pt] to ]=DIS[X]1Q [尾]LST [Pt]
      }
    }
  }
  if(V[t]=t),first,sizeof(一)
  return VIS[T]T;
}
int dfs(int x,int 林)
  if(x==t)return lim;
  int flow=0,a;
  for(int Pt=高音的[X];Pt!=-1;pt=LST [ Pt]。下一步)
    高音的[ X ]=pt;
    if(LST〔Pt〕W&&dis[lst[pt].to]==dis[x]+1(a=DFS(LST [Pt])。,min(LST[Pt]),lim-工艺过程)
      LST〔Pt〕Wa;1].w+=a;flow+=a;
      if(flow==lim)return flow;
    }
  }
  return flow;
}
int dinic(){
  int ans=0,x;
  while(BFS)
    while(x=dfs(s,INF)x;
  return ans;
}
int totflow[maxn];
void Add(int a,int b,int lo,int hi,int 努姆)
  totflow[a]ToFLUT[B]lo;
  addedge(a,b,hi-lo,努姆)
}
int 低[记号斯],ANS[MACM]
int n,m,tot;
void bound_flow(){
  int sum=0;
  for(int i=s;i<=t;++i){
    if(totflow[i]<0){
      addedge(i,tt,-totflow[i],0);
    }else{
      sum+=totf低[我]
      addedge(ss,i,totflow[i],0);
    }
  }
  addedge(t,s,0x7f7f7f7f,0);
  int tmps=s,tmpt=t;
  sttt;
  if(第尼克)和)
    for(int Pt=高音的[SS];Pt!=-1;pt=LST [ Pt]。下一步)
      LST〔Pt〕WLST1].w=0;
    }
    for(int Pt=高音的[TT];Pt!=-1;pt=LST [ Pt]。下一步)
      LST〔Pt〕WLST1].w=0;
    }
    int flow0=LSE-1].w;
    LSE-1].w=LSE-2].w=0;
    sTMPStmpt;
    printf("%d\n",flow0+dinic());
    for(int i=1;i<=m;++i){
      for(int pt=first[i+n];pt!=-1;pt=LST [ Pt]。下一步)
    if(LST [Pt] num!=0){
      ANS[LST[Pt]·num ]=LST〔Pt〕W+低[LST[Pt]·num ]
    }
      }
    }
    for(int i=1;i<=tot;++i)printf("%d\n",ANS[I]
  }else{
    printf("-1\n");
  }
}

void work(){
  s=0;t=n+m+1;
  ss=n+m+2;tt=n+m+3;
  memset(first,-1,sizeof(一)len=0;
  memset(totflow,0,sizeof(totflow));
  int x,y;
  for(int i=1;i<=m;++i){
    scanf("%d",&x);
    添加(n)+i,t,x,inf,0);
  }
  int l,h;
  tot=0;
  for(int i=1;i<=n;++i){
    scanf("%d%d",&x,&y);
    添加(S),i,0,y,0);
    for(int j=1;j<=x;++j){
      ++tot;
      scanf("%d%d%d",&y,&l,&h);
      添加(i),n+y+1,l,h,低;l;
    }
  }
  bound_flow();printf("\n");
}
int main(){
  while(斯坎夫"%d%d",&n,&m)!=EOF任务
  return0;
}

4.起作用的汇有上下界最小流

训练:广播网如今有单独。源点s宽恕点T,找到条浜使得源点的总卸船量本利积和汇点的总流入量,另一边点清偿过的行程避免浪费。,并且每条边的流量清偿过的上限和下界限度局限.在这些作出前提下要价最小总流量.

依然是先跑出单独起作用的汇切实可行的流.这时候的流也未必是最小的.假设we的自己人格形式能在残量广播网上找到条s-t的路线使得搞掉这条路线上的流量以前依然清偿过的流量下限,we的自己人格形式就可以记下单独更小的流.仿佛we的自己人格形式并缺少什么算法可以”找到放量多的可以去除流量的路线”

这时候必要we的自己人格形式再包含一下dinic的反向边.反向边的流量放均等于正向边的的流量增加.因而we的自己人格形式在残量广播网上找出t到s的流就相当于减小了s到t的流,因而we的自己人格形式在跑出切实可行的流的残量广播网上跑t-s最大流,用切实可行的流的大量减去在这场合t-s最大流的大量执意最小流的大量.(t-s最大流实则是放量减缩s-t取向的流).

问:它会增加交通到下限的交通吗?

不,它与最大流量的下限和下限俱。,we的自己人格形式曾经发生了初始流量从每一侧的交通与SIZ。,这些流量不在意的we的自己人格形式建出的图中.最顶点的境况是减缩到自己人边的流量本利积和流量下限,它不能的更小。

信号:bzoj2502 清扫雪路

#include
#include
#include
usingnamespace std;
constint maxn=205,maxm=100005;
struct edge{
  int to,next,w;
LST[MACM]int len=0,first[maxn],_first[maxn];
void addedge(int a,int b,int w){//PrdTf(添加 %d %d\n",a,b);
  LST=b;LSE].next=first[a];LSE].w=w;first[a]=len++;
  LST=a;LSE].next=first[b];LSE].w=0高音的[B]=Le;
}
int q[maxn],vis[maxn],dis[maxn],head,tail,s,t,T,ss,tt;
bool bfs(){
  head=tail=0;VIS[S]=++T;dis[s]=1Q [尾]s;
  while(头)!=搭上)
    int x=q[head++];
    for(int Pt=高音的[X];Pt!=-1;pt=LST [ Pt]。下一步)
      if(LST [Pt] W&&VIS[LST[Pt] to)!=T){
    Vist[LST[Pt] to ]DIS[LST[Pt] to ]=DIS[X]1Q [尾]LST [Pt]
      }
    }
  }
  if(V[t]=t),first,sizeof(一)
  return VIS[T]T;
}
int dfs(int x,int 林)
  if(x==t)return lim;
  int flow=0,a;
  for(int Pt=高音的[X];Pt!=-1;pt=LST [ Pt]。下一步)
    高音的[ X ]=pt;
    if(LST〔Pt〕W&&dis[lst[pt].to]==dis[x]+1(a=DFS(LST [Pt])。,min(LST[Pt]),lim-工艺过程)
      LST〔Pt〕Wa;1].w+=a;flow+=a;
      if(flow==lim)return flow;
    }
  }
  return flow;
}
int dinic(){
  int ans=0,x;
  while(BFS){
    while(x=dfs(s,0x7f7f7f7f))ans+=x;
  }
  return ans;
}
int totflow[maxn];
void del(int x){
  for(int Pt=高音的[X];Pt!=-1;pt=lst[pt].next)LST〔Pt〕WLST1].w=0;
}
int main(){
  int 斯堪夫"%d",&n);
  int x,y;
  memset(first,-1,sizeof(一)
  for(int i=1;i<=n;++i){
    scanf("%d",&x);
    for(int j=1;j<=x;++j){
      scanf("%d",&y);
      totflow[i]--;totflow[y]++;
      addedge(i,y,0x7f7f7f7f);
    }
  }

  s=0;t=n+1;ss=n+2,tt=n+3;
  for(int i=1;i<=n;++i){
    addedge(s,i,0x7f7f7f7f);
    addedge(i,t,0x7f7f7f7f);
  }
  for(int i=1;i<=n;++i){
    if(totflow[i]<0){
      addedge(i,tt,-totflow[i]);
    }else{
      addedge(ss,i,totflow[i]);
    }
  }
  addedge(t,s,0x7f7f7f7f);
  int tmps=s,tmpt=t;
  sttt;
  dinic();
  int flow0=LSE-1].w;
  LSE-1].w=LSE-2].w=0;
  Del(SS)
  s甲状旁腺效能官能过度tmps;
  printf("%d\n",flow0-dinic());
  return0;
}

5.起作用的汇有上下界费流(待填坑,bzoj3876和Codeforces 708D,不外这两道题都可以诉讼费流的手法远上下界广播网流)

发表评论

电子邮件地址不会被公开。 必填项已用*标注