• 最大流 费用流 Dinic && ISAP


    Dinic:

    int vis[MAXN], d[MAXN];
    bool bfs(cint s, cint t){
        queue<int> q;   q.push(s);
        memset(vis, 0, sizeof(vis));
        d[s]=0;     vis[s]=1;
        while(!q.empty()){
            int u=q.front();    q.pop();
            for(int i=h[u]; i!=-1; i=e[i].nxt){
                int v=e[i].v, cap=e[i].cap, ef=e[i].flow;
                if(!vis[v] && cap>ef){
                    d[v]=d[u]+1;
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
        return vis[t]==1;
    }
     
    int cur[MAXN];
    int dfs(int u, int a, cint &t){
        if(u==t || !a) return a;
        int f, flow=0;
        for(int &i=cur[u]; i!=-1; i=e[i].nxt){
            int v=e[i].v, cap=e[i].cap, ef=e[i].flow;
            if(d[v]==d[u]+1 && (f=dfs(v, MIN(a, cap-ef), t))>0){          //注意>0不要放错地方了,会WA的。。。
                flow+=f;
                e[i].flow+=f;
                e[i^1].flow-=f;
                a-=f;
                if(!a) break;
            }
        }
        return flow;
    }
     
    int Dinic(cint s, cint t, cint n){
        int i, flow=0;
        while(bfs(s, t)){
            for(i=0; i<n; i++) cur[i]=h[i];
            flow+=dfs(s, INF, t);
        }
        return flow;
    }
    

    ISAP:

    int cur[MAXN], d[MAXN];
     
    bool done[MAXN];
    void bfs(int t){                                     //reverse bfs
        queue<int> q;
        memset(done, 0, sizeof(done));  done[t]=true;
        d[t]=0;         q.push(t);
        while(!q.empty()){
            int u=q.front();    q.pop();
            for(int i=h[u]; i!=-1; i=e[i].nxt){
                int v=e[i^1].u, flow=e[i^1].flow, cap=e[i^1].cap;   //attention 'u'
                if(cap>flow && !done[v]){
                    done[v]=true;
                    d[v]=d[u]+1;
                    q.push(v);
                }
            }
        }
    }
     
    int num[MAXN], p[MAXN];
     
    int Augment(int s, int t){                          //similar to Edmonds-Karp
        int u=t, a=INF;
        while(u!=s){
            a=MIN(a, e[p[u]].cap-e[p[u]].flow);
            u=e[p[u]].u;
        }
        for(u=t; u!=s; u=e[p[u]].u){
            e[p[u]].flow+=a;
            e[p[u]^1].flow-=a;
        }
        return a;
    }
    int isap(int s, int t){
        int flow=0, i;
        bfs(t);
        memset(num, 0, sizeof(num));
        for(i=0; i<t+1; i++) num[d[i]]++;
        int u=s;
        for(i=0; i<t+1; i++) cur[i]=h[i];
        while(d[s]<t+1){
            if(u==t){
                flow+=Augment(s, t);
                u=s;
            }
            bool ok=false;
            for(int i=cur[u]; i!=-1; i=e[i].nxt){           //advance
                int v=e[i].v, flow=e[i].flow, cap=e[i].cap;
                if(cap>flow && d[u]==d[v]+1){
                    ok=true;
                    p[v]=i;
                    cur[u]=i;
                    u=v;
                    break;
                }
            }
            if(!ok){                                    //retreat
                int tmp=t;
                for(int i=h[u]; i!=-1; i=e[i].nxt) if(e[i].cap>e[i].flow)
                    tmp=MIN(tmp, d[e[i].v]);
                if(--num[d[u]]==0) break;               //gap improvement
                num[d[u]=tmp+1]++;
                cur[u]=h[u];
                if(u!=s) u=e[p[u]].u;
            }
        }
        return flow;
    }
    

     费用流:

    int d[MAXN], p[MAXN], inq[MAXN];
    int a[MAXN];
    void mcmf(cint s, cint t, cint n, int &mincst, int &maxflow){
        mincst=maxflow=0;
        while(1){
            queue<int> q;   q.push(s);
            memset(inq, 0, sizeof(inq));
            for(int i=0; i<n; i++) d[i]=INF;
            inq[s]=1;   d[s]=0;
            a[s]=INF;
            while(!q.empty()){
                int u=q.front();    q.pop();    inq[u]=0;
                for(int i=h[u]; i!=-1; i=e[i].nxt){
                    int v=e[i].v, cap=e[i].cap, ef=e[i].flow, cst=e[i].cst;
                    if(d[v]>d[u]+cst && cap>ef){
                        d[v]=d[u]+cst;
                        a[v]=MIN(a[u], cap-ef);
                        p[v]=i;
                        if(!inq[v]) q.push(v), inq[v]=1;
                    }
                }
            }
            if(d[t]==INF) break;
            maxflow+=a[t];
            mincst+=a[t]*d[t];
            for(int u=t; u!=s; u=e[p[u]].u){
                e[p[u]].flow+=a[t];
                e[p[u]^1].flow-=a[t];
            }
        }
    }
    
  • 相关阅读:
    Leetcode Valid Sudoku
    Leetcode Surrounded Regions
    LeetCode Sqrt
    LeetCode POW
    LeetCode Next Permutation
    ACK-Ackermann, 阿克曼函数
    再不懂时序就 OUT 啦!,DBengine 排名第一时序数据库,阿里云数据库 InfluxDB 正式商业化!
    阿里云提供全托管 ZooKeeper
    性能压测中的SLA,你知道吗?
    第一个入驻阿里云自营心选商城,如今它已经是营收过亿的SaaS独角兽
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3354788.html
Copyright © 2020-2023  润新知