最大流 费用流 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];
        }
    }
}

 

posted @ 2013-10-06 22:58  Ramanujan  阅读(307)  评论(0编辑  收藏  举报