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

实则首要是为了本人的留下印象。

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

有上下界的电网流的果核是”整齐的”,朕经过独身不明确的F的初始流量来整齐的独身可经营的的流量。,最大/最小流量也可以从可经营的的整齐的,而不是基本要素的。

安心的经用灵巧是源汇和动词被动形式汇流(回路流)的替换更动词被动形式吸收能力可经营的流的求解,安心有效的汇的上下界电网流都要用到如此灵巧.

  1. 被动语态汇有上下界可经营的流(执意,回路延续)

形成图案:独身电网,找到一件商品小河,因而每个充盈的延续得是>李。<=Hi,每个点得消除总流入量=总植物似地生长量(流量对自然环境的保护)(如此流的特点是回路往复,无始无终).

如此算法是有上下界电网流算法的根底,供给朕对算法受胎深化的知情,安心算法,因而,我尝试在大围绕中解说该算法的思惟和特殊性。

可经营的流算法的果核是将独身令人不满的事物流量对自然环境的保护的初始流整齐的成消除流量对自然环境的保护的流.

流量对自然环境的保护,执意,每个点的总流入量=总植物似地生长量。

假使有可经营的的连贯,这么必然消除每条边的流量都大于相当的流量的下限.因而朕可以令每条边的流量相当的流量下限,获取初始流量。,以后建出如此流的残量电网.(即:每条边的流量相当的这条边的流量下限与流量下限之差)如此初始流不明确的消除流量对自然环境的保护,因而终极的可经营的流必然是在如此初始流的根底上增大了某一边的流量使得所相当消除流量对自然环境的保护.

因而,朕思索独身不满的廉价出售的图书流量。,依据使附加流与朕的初始流合以消除C

假使某个点在接受边流量相当的下界的初始流中消除流量对自然环境的保护,这点也消除了附加流说话中肯延续对自然环境的保护。,

假使独身点比初始流说话中肯植物似地生长有更多的流入,则,这点在附加流说话中肯植物似地生长量大于

假使独身点在初始流中流入心不在场的焉植物似地生长,x,因而,这点在附加流说话中肯植物似地生长量心不在场的焉

         可以以为附加流中一件商品从u到v的使渐进的独身流量代表将原图中u到v的流量增大1

x的数值可以数x的接受边,更近便的。,A[i]表明I在初始延续说话中肯流入植物似地生长。,A[I]的正和负表现流入私下的相干。,接下来,朕运用独身[I]表现I在初始FLO说话中肯流入和植物似地生长。

但是,DIIC算法可以找到柔韧的宿SA的最大流。,不克不及在原电网上立即的求独身这样地的被动语态汇且令人不满的事物流量对自然环境的保护的附加流.注意到附加流是在原电网上令人不满的事物流量对自然环境的保护的,这激起了朕在原始电网在远处添加某一充盈和点。,这些边和点用于获得交通流的限度局限。

详细地,假使独身点i在原电网上的附加流中必要消除流入量>植物似地生长量(初始流中流入量<植物似地生长量,A[i]<0),这么朕必要给多的流入量找独身去处,因而朕使被安排好独身i动身延续的充盈= -a[i]。假使[i]>0,执意,朕必要在附加流>流入中植物似地生长。,朕必要让更多的资产植物似地生长。,因而朕使被安排好关系i延续的充盈= a[i]

自然,朕也必要有独身放置来重行开端。,此外一种办法可以标点我的充盈。,因而朕新建独身挂名的源点ss和独身挂名的汇点tt(双写字母是为了和有效的汇电网流说话中肯源点s汇点t相区别).新建的标点i的边都从ss动身,从我的边标点独身点TT。或侧面的到TT。,任何侧面的都是人SS。,

TT充盈总流量的下限得相当的UPP的下限。,因每个边都有两个正和负A[I]相当的奉献,因而,所相当A[i]的和相当的0。,执意,心不在场的焉0的总和的模数=模数O。

假使朕能找到消除新添加剂的流,则边是满的。,最初的流的使分开是朕必要的附加流。,“新加的边都满流”和”附加流合上初始流腰槽流量均衡的流”是相等的约束条件).

这么朕怎样才能找到一件商品盛产延续的充盈的新连贯呢?朕可以看一眼假设,这样地的流得是朕建筑的的图的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,找到一件商品小河使得源点的总植物似地生长量相当的汇点的总流入量,安心点消除延续对自然环境的保护。,并且每条边的流量消除最高的和下界限度局限.

源和汇令人不满的事物流量对自然环境的保护。,这使朕很难做到这点。,因而朕想办法把成绩转变成轻易处置的每个点都消除流量对自然环境的保护的被动语态汇境遇.

为了使源汇消除流量对自然环境的保护,朕必要有充盈流入点S。,T.早已注意到S的植物似地生长相当的T的流入。,朕就可以从汇点t向源点s连一件商品下界为0最高的为无量大的边,相当于把从源点s植物似地生长的流量再流后面.在这样地的图中套用上面的算法求出独身可经营的的回路流,经过将T从汇点移除到源点S,独身可经营的的Act

这时有独身小成绩:驾驶CON的终极可经营的流量是多少?

可以找到,在回路流中得消除S植物似地生长的总流量。,让原始图中心不在场的焉边流入S。,S植物似地生长的延续是从T到S的神边流。,执意s-t可经营的流的流量.因而朕不可更改的看一下t到s的无量边的流量(即dinic跑完以后反向边的权值)那就够了知情原图中有效的汇可经营的流的流量.

信号:如此可经营的流算法在有效的汇有上下界最大流/最小流中大主教区用到,你可以参观上面两个算法的信号。

3.有效的汇有上下界最大流

形成图案:电网现时有独身。源点s支付点T,找到一件商品小河使得源点的总植物似地生长量相当的汇点的总流入量,安心点消除延续对自然环境的保护。,并且每条边的流量消除最高的和下界限度局限.在这些必要条件下必要条件总流量最高的.

率先套用上面的算法求出独身有效的汇有上下界可经营的流.此刻的流不明确的最大.

接下来,在廉价出售的图书电网上运转S-最大流。

终极的最大流流量=可经营的流流量(即t到s的无量使渐进跑出的流量)+新增广出的s-t流量

成绩:当非常边令人不满的事物TR的下限时,它会放针吗?

无力的.因朕一开端建的图执意把形成大块相当的流量下限的流量拿出去以后的残量电网,用图表示说话中肯交通不谢。

信号: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,找到一件商品小河使得源点的总植物似地生长量相当的汇点的总流入量,安心点消除延续对自然环境的保护。,并且每条边的流量消除最高的和下界限度局限.在这些必要条件下必要条件最小总流量.

依然是先跑出独身有效的汇可经营的流.这时候的流都不的明确的是最小的.假设朕能在残量电网上找到一件商品s-t的小路使得除掉这条小路上的流量以后依然消除流量下限,朕就可以腰槽独身更小的流.仿佛朕并心不在场的焉什么算法可以”找到放量多的能去除流量的小路”

这时候必要朕再拘押一下dinic的反向边.反向边的流量放针相等于正向边的的流量减缩.因而朕在残量电网上找出t到s的流就相当于减小了s到t的流,因而朕在跑出可经营的流的残量电网上跑t-s最大流,用可经营的流的形成大块减去在这场合t-s最大流的形成大块执意最小流的形成大块.(t-s最大流实则是放量减缩s-t关系的流).

问:它会减缩交通到下限的交通吗?

不,它与最大流量的下限和下限相似的。,朕早已发生了初始流量从每一侧的交通与SIZ。,这些流量不在场的朕建出的图中.最顶点的境遇是减缩到接受边的流量相当的流量下限,它无力的更小。

信号: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,不外这两道题都可以代价流的灵巧逃脱上下界电网流)

发表评论

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