最大流的SAP算法模板

明天补充~~~先上代码

#include<iostream>
#include<string>
#include<queue>
#include<vector>
#include<stack>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>

using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn =500+10;


struct Edge{
    int v,cap,next;
}edge[maxn];
int n,m,ne,nv;
int head[maxn],pre[maxn],level[maxn],gap[maxn],cur[maxn];
void addEdge(int u,int v,int cap){
    edge[ne].v=v;
    edge[ne].cap=cap;
    edge[ne].next=head[u];
    head[u]=ne++;

    edge[ne].v=u;
    edge[ne].cap=0;
    edge[ne].next=head[v];
    head[v]=ne++;
}
void bfs(int vt){
    memset(level,-1,sizeof(level));
    memset(gap,0,sizeof(gap));
    level[vt]=0;
    gap[level[vt]]++;
    queue<int>q;
    q.push(vt);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].v;
            if(level[v]!=-1){
                continue;
            }
            level[v]=level[u]+1;
            gap[level[v]]++;
            q.push(v);
        }
    }
}
int SAP(int vs,int vt){
    bfs(vt);
    memset(pre,-1,sizeof(pre));
    memcpy(cur,head,sizeof(head));
    pre[vs]=vs;
    gap[0]=nv;
    int u=vs,max_flow=0,flow=inf;
    while(level[vs]<nv){
        bool flag=false;
        for(int &i=cur[u];i!=-1;i=edge[i].next){
            int v=edge[i].v;
            if(edge[i].cap&&level[u]==level[v]+1){
                flag=true;
                pre[v]=u;
                u=v;
                flow=min(flow,edge[i].cap);
                if(v==vt){
                    max_flow+=flow;
                    for(u=pre[v];v!=vs;v=u,u=pre[u]){
                        edge[cur[u]].cap-=flow;
                        edge[cur[u]^1].cap+=flow;
                    }
                    flow=inf;
                }
                break;
            }
        }
        if(flag){
            continue;
        }
        int ml=nv;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].v;
            if(edge[i].cap&&level[v]<ml){
                ml=level[v];
                cur[u]=i;
            }
        }
        if(--gap[level[u]]==0){
            break;
        }
        level[u]=ml+1;
        gap[level[u]]++;
        u=pre[u];
    }
    return max_flow;
}
int main(){
    while(~scanf("%d%d",&m,&nv)){
        memset(head,-1,sizeof(head));
        ne=0;
        for(int i=1;i<=m;i++){
            int u,v,cap;
            scanf("%d%d%d",&u,&v,&cap);
            addEdge(u,v,cap);
        }
        printf("%d\n",SAP(1,nv));
    }
    return 0;
}

  

 

posted @ 2018-04-08 13:14  愿~得偿所愿,不负时光  阅读(165)  评论(0编辑  收藏  举报