• 网络流相关模板及结论


    一、一些结论 

      1、最大流最小割定理(Maximum Flow, Minimum Cut Theorem):网络的最大流等于最小割

      2、任意一个流都小于等于任意一个割(废话)

      3、(hdu 6214)最小割的割边一定满流,但是满流的边不一定是最小割的割边。(割边必满流,满流不一定是割边)

      4、拆点:目的是让,每个点通过的流量为1。

    对于一个网络流图G=(V,E),其中有源点s和汇点t,那么下面三个条件是等价的:
    1. 流f是图G的最大流
    2. 残留网络Gf不存在增广路
    3. 对于G的某一个割(S,T),此时f = C(S,T)

     二、模板

      1、Dinic(多路增广+当前弧优化)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN=1e4+3,MAXM=1e5+3,INF=0x7fffffff;
     4 struct ppp{
     5     int from,to,flow,next;
     6 }edge[MAXM<<1];
     7 int head[MAXN],tot,n,m,s,t,maxflow,vis;
     8 int dep[MAXN],vztd[MAXN],cur[MAXN];//cur µ±Ç°»¡ 
     9 void add(int u,int v,int w)
    10 {
    11     edge[tot]=(ppp){u,v,w,head[u]};
    12     head[u]=tot;
    13     tot++;
    14 }
    15 bool bfs()
    16 {
    17     for(int i=1;i<=n;i++)    
    18         cur[i]=head[i],dep[i]=0x3f3f3f3f,vztd[i]=0;
    19     dep[s]=0;
    20     queue<int>q;
    21     q.push(s);
    22     while(!q.empty())
    23     {
    24         int k=q.front();
    25         q.pop();
    26         vztd[k]=0;
    27         for(int i=head[k];i!=-1;i=edge[i].next)
    28         {
    29             int d=edge[i].to,lef=edge[i].flow;
    30             if(dep[d]>dep[k]+1 and lef)
    31             {
    32                 dep[d]=dep[k]+1;
    33                 if(!vztd[d])
    34                 {
    35                     q.push(d);
    36                     vztd[d]=1;
    37                 }
    38             }
    39         }
    40     }
    41     if(dep[t]!=0x3f3f3f3f)    return 1;
    42     return 0;
    43 }
    44 int dfs(int u,int flow)
    45 {
    46     if(u==t)    
    47     {
    48     //    vis=1;
    49         maxflow+=flow;
    50         return flow;
    51     }
    52     int used=0;
    53     for(int i=cur[u];i!=-1;i=edge[i].next)
    54     {
    55         cur[u]=i;
    56         int d=edge[i].to;
    57         int lef=edge[i].flow;
    58         if(lef and dep[d]==dep[u]+1)
    59         {
    60             int low=dfs(d,min(flow-used,lef));
    61             if(low)
    62             {
    63                 used+=low;
    64                 edge[i].flow-=low;
    65                 edge[i^1].flow+=low;
    66                 if(used==flow)    break;
    67             }
    68         }
    69     }
    70     return used;
    71 }
    72 int dinic()
    73 {
    74     while(bfs())
    75         dfs(s,INF);
    76     return maxflow;
    77 }
    78 int main()
    79 {
    80     scanf("%d%d%d%d",&n,&m,&s,&t);
    81     memset(head,-1,sizeof(head));
    82     for(int i=1;i<=m;i++)
    83     {
    84         int u,v,w;
    85         scanf("%d%d%d",&u,&v,&w);
    86         add(u,v,w);
    87         add(v,u,0);
    88     }
    89     printf("%d",dinic());
    90     return 0;
    91 }
    View Code

      2、ISAP(加了当前弧怎么还慢了20msQAQ)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAX=1e4+3,MAXM=1e5+5,INF=0x7fffffff;
     4 struct ppp{
     5     int to,next,flow;
     6 }edge[MAXM<<1];
     7 int head[MAX],dep[MAX],gap[MAX],cur[MAX];
     8 int n,m,s,t,tot,maxflow=0;
     9 void add(int u,int v,int w)
    10 {
    11     edge[tot]=(ppp){v,head[u],w};
    12     head[u]=tot;
    13     tot++;
    14 }
    15 void bfs()
    16 {
    17     memset(dep,-1,sizeof(dep));
    18     memset(gap,0,sizeof(gap));
    19     dep[t]=0;
    20     gap[0]=1;
    21     queue<int>q;
    22     q.push(t);
    23     while(!q.empty())
    24     {
    25         int u=q.front();
    26         q.pop();
    27         for(int i=head[u];i!=-1;i=edge[i].next)
    28         {
    29             int v=edge[i].to;
    30             if(dep[v]!=-1)    continue;
    31             q.push(v);
    32             dep[v]=dep[u]+1;
    33             gap[dep[v]]++;
    34         }
    35     }
    36     return ;
    37 }
    38 inline int dfs(int u,int flow)
    39 {
    40     if(u==t)
    41     {
    42         maxflow+=flow;
    43         return flow;
    44     }
    45     int used=0;
    46     for(int i=cur[u];i!=-1;i=edge[i].next)
    47     {
    48         cur[u]=i;
    49         int v=edge[i].to;
    50         if(edge[i].flow and dep[v]+1==dep[u])
    51         {
    52             int low=dfs(v,min(flow-used,edge[i].flow));
    53             if(low)
    54             {
    55                 edge[i].flow-=low;
    56                 edge[i^1].flow+=low;
    57                 used+=low;
    58             }
    59             if(used==flow)    return used;
    60         }
    61     }
    62     gap[dep[u]]--;
    63     if(gap[dep[u]]==0)    dep[s]=n+1;
    64     dep[u]++;
    65     gap[dep[u]]++;
    66     return used;
    67 }
    68 int isap()
    69 {
    70     bfs();
    71     while(dep[s]<n)    
    72     {
    73         memcpy(cur,head,sizeof(head));
    74         dfs(s,INF);
    75     }
    76     return maxflow;
    77 }
    78 int main()
    79 {
    80     scanf("%d%d%d%d",&n,&m,&s,&t);
    81     memset(head,-1,sizeof(head));
    82     for(int i=1;i<=m;i++)
    83     {
    84         int u,v,w;
    85         scanf("%d%d%d",&u,&v,&w);
    86         add(u,v,w);
    87         add(v,u,0);
    88     }
    89     printf("%d",isap());
    90     return 0;
    91 }
    View Code

      3、HLPP

    -

  • 相关阅读:
    设置QtCreator多核编译
    ZeroMQ研究与应用分析及学习资料
    彻底卸载Visual Studio 2013、Visual Studio 2015
    delphi 动态设置和访问cxgrid列的Properties
    delphi 拷贝文件时有进度显示
    Delphi 连接mysql的功能,去除乱码, 需要设置字符集
    cxGrid1 的使用方法
    Django day12 分页器
    Django day11(一) ajax 文件上传 提交json格式数据
    Django day08 多表操作 (五) 常用和非常用用字段
  • 原文地址:https://www.cnblogs.com/member-re/p/10403065.html
Copyright © 2020-2023  润新知