网络流总结

琐记

这玩意是之前寒假集训时学二分图时被忽悠去学的,今天又回去复习了一下,想写篇总结。


其他的后面有时间再来填坑,先咕着。。。


最大流最小割定理

内容:任何一个网络的最大流量等于最小割中的边容量之和

这玩意看蓝书解释没咋懂,我自己感性理解了一下,有不对的各位指点一下啊

一定注意,网络流的图是有向无环图

假设我们现在有如下的网络,
image

网络中的边我们可分为三类:

  • 1:满流边
  • 2:被满流边影响的边(不满流但有流量)
  • 3:不含流量的边(即不被影响的边)

其最大流为7,我们要寻找一些边让他割去使得S与T不连通,很显然我们要在上面一条路S-A-B-T和下面一条路S-C-D-E-T中

都至少选择一条路将其割掉,而我们要使割去的流量最小,那一定是去割有流量的边(不然你割他干啥),而这些有流量的边中

一定存在至少一条满流的情况才能构成最大流,而这满流的边可能是由之前多条边的流量之和,显然,这之前多条边的流量之和

一定大于等于流量之和,为使S和T不连通,这条路上我们要么割去这条满流的边,要么把其前面的边全割去才能保证这条路不

通,如果只割之前边一部分的话,那另一部分肯定可以与满流的边相连达到连通的目的,所以对于这条路,他的最大流即为

其最小割,而整张网络的流量是由很多这样的满流边和其影响的边组成,均符合上述情况。而那些没有流量的边为什么不用

被考虑呢,首先这些边肯定不与T相连,不然他肯定可以是满流边或被其影响的边之一,其次这些边上没有流量是因为这些边

位置右边的边肯定有满流的了,且其前面没有小于后面那边流量的满流的边(不然不是最大流),那我们割的话肯定是割右边

那个满流的边更优,所以我们直接就将后面的满流边割去即可,这种边割去后即保证了最优也保证了没流的边与后面的T断了

如果后面的边不满流,前面的边满流了,同样割去满流的边更优,这样就是让其与前面的S断了,这种边实际上就是那些被潜

在影响的边,就像图中的C-B一样,它的流量是被别的边给“抢了”,这也是为什么不会出现割去边后原来没有流量的边使S与T

联通的原因。

综上,割满流边,让被满流边影响的边和没流量的边与S或T中的一个不连通,出来的值即为最小割,同为最大流

Dinic算法

残量网络

定义:网络中所有节点及剩余流量大于0的边组成的图

层次

定义:从原点到一个点至少需要经过几条边即为这个点的层次

分层图

定义:在残量网络中根据每个点的层次将点划为不同的点集,其组成的这个子图即为分层图

\(Dinic\)算法就是不断在网络中构造分层图,然后\(dfs\)更新流量,直到残量网路不能联通 \(S\)\(T\) ,复杂度上界 \(n^{2}m\)

板子
int deep[MAXN],a[MAXN];
queue<int>q;
bool bfs()
{
    for(int i=1;i<=t;i++)deep[i]=0;
    deep[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        a[u]=head[u];
        for(int i=head[u];i;i=m[i].nxt)
        {
            if(!deep[m[i].to]&&m[i].dis>m[i].flow)
            {
                deep[m[i].to]=deep[u]+1;
                q.push(m[i].to);
            }
        }
    }
    return deep[t];
}
int dfs(int now,int fa1)
{
    if(now==t||!fa1)return fa1;
    int fa=0,d;
    for(int i=a[now];i;i=m[i].nxt)
    {   
        a[now]=i;
        if(deep[m[i].to]==deep[now]+1&&(d=dfs(m[i].to,min(fa1-fa,m[i].dis-m[i].flow))))
        {
            m[i].flow+=d;
            m[i^1].flow-=d;
            fa+=d;
            if(fa==fa1) break;
        }
    }
    return fa;
}
void dinic()
{
    int res=0;
    while(bfs())
    {
        res+=dfs(0,INF);
    }
    printf("%d\n",res);
}
posted @ 2024-05-04 12:16  _君の名は  阅读(17)  评论(0编辑  收藏  举报