网络流总结

Posted tply

tags:

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

网络流专题

Part1 一些代码

(一)初始处理

1.最大流加边

struct Edge{int to,nxt,w;}e[SZ]; // w:流量
int Ecnt=2,Ehead[SZ];
il void Eadd(int u,int v)
{
    e[Ecnt]=(Edge){v,Ehead[u],1};
    Ehead[u]=Ecnt++;
    e[Ecnt]=(Edge){u,Ehead[v],0};
    Ehead[v]=Ecnt++;
}

2.费用流加边

struct Edge{int to,nxt,w,c;}e[SZ]; //w:流量,c:费用
int Ehead[SZ],pv[SZ],pe[SZ],Ecnt=2;
il void Eadd(int u,int v,int w,int cost)
{
    e[Ecnt]=(Edge){v,Ehead[u],w,cost};
    Ehead[u]=Ecnt++;
    e[Ecnt]=(Edge){u,Ehead[v],0,-cost};
    Ehead[v]=Ecnt++;
}
// pv[i] : spfa时使得i点dis值松弛的节点
//(最短路的上一节点)
//pe[i] : i与pv[i]连接的边

3.注意事项

对于原点和汇点 s = 0,t=n+2
Ecnt(边的起始编号)=2(一定不能是1)

(二)板子

1.最大流

int lev[SZ];
il bool bfs()
{
    rg u,v;queue <int> Q;
    memset(lev,-1,sizeof(lev));
    lev[s]=1,Q.push(s);
    while(!Q.empty())
    {
        u=Q.front(),Q.pop();
        for(rg i=Ehead[u];i;i=e[i].nxt)
        {
            v=e[i].to;
            if(e[i].w>0&&lev[v]<0)
            {
                lev[v]=lev[u]+1;
                Q.push(v);
            }
        }
    }
    if(lev[t]>0) return 1;
    return 0;
}
int cur[SZ],Ans;
int dfs(int u,int f)
{
    if(u==t||f==0) return f;
    for(int &i=cur[u];i;i=e[i].nxt)
    {
        rg di=0,v=e[i].to;
        if((lev[v]==lev[u]+1)&&(e[i].w>0))
         if(di=dfs(v,min(f,e[i].w)))
         {
            e[i].w-=di,e[i^1].w+=di;
            return di;
         }
    }
    return 0;
}
il void maxflow()
{
    rg di=0;
    while(bfs())
    {
        for(rg i=s;i<=t;++i) cur[i]=Ehead[i];
        while((di=dfs(s,INF))&&(Ans+=di));
    }
    printf("%d",Ans);
}

2.费用流

ll dis[SZ];
int vis[SZ];
queue <int> Q;
bool spfa()
{
    memset(dis,63,sizeof(dis));
    dis[s]=0; Q.push(s);
    while(!Q.empty())
    {
        rg u=Q.front();
        Q.pop();
        for(rg i=Ehead[u];i;i=e[i].nxt)
        {
            rg v=e[i].to;
            if((e[i].w)&&(dis[v]>dis[u]+e[i].c))
            {
                dis[v]=dis[u]+e[i].c;
                pe[v]=i;
                pv[v]=u;
                if(!vis[v])
                {
                    vis[v]=1;
                    Q.push(v);
                }
            }
        }
        vis[u]=0;
    }   
    return dis[t]<dis[0];
}
il void costflow()
{
    ll Ans=0;
    while(spfa())
    {
        rg di=INF;
        for(rg i=t;i!=s;i=pv[i])
         di=min(di,e[pe[i]].w);
        for(rg i=t;i!=s;i=pv[i])
        {
            e[pe[i]].w-=di;
            e[pe[i]^1].w+=di;
            Ans+=1ll*di*e[pe[i]].c;
        }
    }
    printf("%lld",Ans);
}

Part2 一些题目

(一) 最长k可重区间集问题

http://www.cnblogs.com/tply/p/8185899.html


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

@总结 - 8@ 上下界网络流等一类网络流问题

2018年十月水题总结

HihoCoder上网络流算法题目建模总结

图论网络流总结

网络流24题-题目总结

「总结」网络流