网络流基础模板

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流基础模板相关的知识,希望对你有一定的参考价值。

//网络流dinic

//最大流=最小割

//基本建模
//建源汇,向每个点分别连所限制的边权,题目所给的边连inf 
int cnt=1;
inline void insert(int u,int v,int w)
{
    e[++cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
    e[cnt].f=w;
}
inline void insert(int u,int v,int w)
{
    insert1(u,v,w);
    insert1(v,w,0);
}
inline int dfs(int now,int f)
{
    if(now==t)    return f;
    for(int i=head[now];i && f;i=e[i].next)
    {
        if(e[i].f && dep[e[i].to]==dep[now]+1)
        {
            int d=dfs(e[i].to,min(e[i].f,f));
            f-=d;ret+=d;e[i].f-=d;e[i^1].f+=d; 
        }
    }
    if(!ret)    dep[now]=-1;
    return ret;
}
inline bool bfs()
{
    memset(dep,0,sizeof(dep));
    q.push(s),dep[s]=1;
    queue<int>    q;
    while(!q.empty())
    {
        int now=q.front();q.pop();
        for(int i=head[now];i;i=e[i].next)
            if(e[i].f && !dep[e[i].to])
                dep[e[i].to]=dep[now]+1,q.push(e[i].to); 
    }
    return dep[t];
}
inline int dinic()
{
    int ret=0;
    while(bfs())    ret+=dfs(s,1e9+7);
    return ret;
} 

//二分图

//建立超级源汇,连边权为1,最大流

//最大匹配=最大流

//最大匹配=最小顶点覆盖
//最大点独立集=最小边覆盖 
//最大匹配+最小边覆盖=最大点独立集+最小顶点覆盖=|V|

//最大权闭合子图
//正点权和-最小割

//二分图点权最大点独立集
//点权和-最小割 

//点限制的网络流
//拆点x0为x1->x2边权为x0的点限制

//费用流
inline int dfs(int now,int f)
{
    if(now==t)
    {
        ans+=f*dis[t];
        return f;
    }
    mark[now]=1;
    int ret=0;
    for(int i=head[now];i && f;i=e[i].next)
    {
        if(e[i].f && dis[now]+e[i].cost==dis[e[i].to] && !mark[e[i].to])
        {
            int d=dfs(e[i].to,min(f,e[i].f));
            e[i].f-=d;
            e[i^1].f+=d;
            ret+=d;
            f-=d;
        }
    }
    return ret;
}
inline bool spfa()
{
    for(int i=0;i<=n+1;i++)        dis[i]=inf;
    memset(vis,0,sizeof(vis));
    memset(mark,0,sizeof(mark));
    q.push(s);vis[s]=1;dis[s]=0;
    while(!q.empty())
    {
        int now=q.front();q.pop();vis[now]=0;
        for(int i=head[now];i;i=e[i].next)
        {
            if(e[i].f && dis[now]+e[i].cost<dis[e[i].to])
            {
                dis[e[i].to]=dis[now]+e[i].cost;
                if(!vis[e[i].to])
                {
                    q.push(e[i].to);
                    vis[e[i].to]=1;
                }
            }
        }
    }
    return dis[t]<inf;
}
inline void insert(int u,int v,int f,int w)
{
    insert1(u,v,f,w);
    insert1(v,u,0,-w);
} 
inline int dinic()
{
    ans=0;
    while(spfa())    dfs(s,inf);
    return ans;
}

//建图才是最难滴 

 

以上是关于网络流基础模板的主要内容,如果未能解决你的问题,请参考以下文章

小程序基础13:模板

模板网络最大流

网络流专题

网络流模板

模板最小费用最大流

模板网络最大流