模板整理: 图论---网络流/最小费用最大流


NOIp……应该不会考这东西吧QAQ
考了感觉药丸。。
还是整一个比较好~
网络流有个特点就是,最坏的上界一般都是达不到的。

1.FF
思路是每次增广1的流量,很慢的,因为容量一般挺大,
没写过,就没模板了。。O( |f|m )(似乎是,有点忘了)

2.EK
思路是随意找一条增广路径,然后增广即可。
最坏O( m2n )。
就写过一次……还是早期写的……真是有点丑的。。


bool EdKa(int src,int des,int n)
{
    int v,i,head,tail;
    memset(visit,0,sizeof(visit));
    head=tail=0;
    Q[tail++]=src;
    visit[src]=true;
    while (head!=tail)
    {
        v=Q[head++];
        for (i=1;i<=n;i++)
            if (!visit[i] && map[v][i])
            {
                Q[tail++]=i;
                visit[i]=true;
                pre[i]=v;
                if (i==des)    return true;
            }
    }
    return false;
}
int maxflow(int src,int des,int n)
{
    int i,_min,sum=0;
    while (true)
    {
        if (!EdKa(src,des,n))
            return sum;
        _min=(1<<30);
        i=des;
        while (i!=src)
        {
            if (_min>map[pre[i]][i])
                _min=map[pre[i]][i];
            i=pre[i];
        }
        i=des;
        while (i!=src)
        {
            map[pre[i]][i]-=_min;
            map[i][pre[i]]+=_min;
            i=pre[i];
        }
        sum+=_min;
    }
}


3.dinic
不会。O( n2m )
什么?我竟然不会dinic??
对啊……因为我菜啊。。
QAQ好吧不过幸好网上dinic模板一堆一堆的,随便找啦!

4.ISAP
一直在用的网络流写法……
也是O( n2m )的,综合来说应该比dinic快一丢。
每次找最短路增广,然后加上当前弧优化(Improved SAP)
然后可以一开始预处理出层次网络(我的写法)。
用BFS预处理出初始层次网络,不过似乎可以中间计算出来?
测试了很多题,觉得这个模板还不错,速度也还可以。

void BFS(){
    memset(gap,0,sizeof(gap));
    memset(d,255,sizeof(d));
    d[sink]=0; gap[0]++;
    int Head=0,tail=1;
    Q[0]=sink;
    while (Head!=tail){
        int u=Q[Head++];
        for (int i=head[u];~i;i=E[i].next){
            int j=E[i].to;
            if (~d[j]) continue;
            d[j]=d[u]+1;
            gap[d[j]]++;
            Q[tail++]=j;
        }
    }
}
int ISAP(){
    BFS();
    memcpy(cur,head,sizeof(cur));
    int u,flow=0;
    u=pre[source]=source;
    while (d[sink]<Ver+1){
        if (u==sink){
            int f=inf,neck;
            for (int i=source;i!=sink;i=E[cur[i]].to)
                if (f>E[cur[i]].C) f=E[cur[i]].C,neck=i;
            for (int i=source;i!=sink;i=E[cur[i]].to)
                E[cur[i]].C-=f,E[cur[i]^1].C+=f;
            flow+=f; u=neck;
        }
        int j;
        for (j=cur[u];~j;j=E[j].next)
            if (E[j].C && d[E[j].to]+1==d[u]) break;
        if (~j){
            pre[E[j].to]=u;
            cur[u]=j;
            u=E[j].to;
        }   else{
            if (!(--gap[d[u]])) break;
            int mind=Ver+1;
            for (int i=head[u];~i;i=E[i].next)
                if (E[i].C && mind>d[E[i].to])
                    cur[u]=i,mind=d[E[i].to];
            d[u]=mind+1;
            gap[d[u]]++;
            u=pre[u];
        }
    }
    return flow;
}


最小费用最大流:
只会最小费用最大流啊。。什么最大费用,最小流这种都不会。。
突然发现以前写过了。。传送门

猜你喜欢

转载自blog.csdn.net/ThinFatty/article/details/78486063