网络流sap算法模版

递归版sap:

#include<cstdio>

#include<iostream>

#include<cstring>

#include<algorithm>

#define N 310

#define M 50010

#define inf 1<<30

using namespace std;

struct Edge{

    int to,val,next;

}edge[M];

int index[N],d[N],gap[N],e;

void addedge(int from,int to,int val)

{

    edge[e].to=to;

    edge[e].val=val;

    edge[e].next=index[from];

    index[from]=e++;

    edge[e].to=from;

    edge[e].val=0;

    edge[e].next=index[to];

    index[to]=e++;

}

int source,des,n,m;

int dfs(int pos,int flow)

{

    if(pos==des)

        return flow;

    int i,j,v,val,lv,mind,c;

    mind=n-1;//初始最小标号为n-1

    lv=flow;

    for(i=index[pos];i!=-1;i=edge[i].next)

    {

        v=edge[i].to;

        val=edge[i].val;

        if(val)

        {

            if(d[v]+1==d[pos])

            {

                c=min(lv,val);//对于该点的最小可行流

                c=dfs(v,c);

                edge[i].val-=c;//更新剩余图

                edge[i^1].val+=c;

                lv-=c;

                if(d[source]>=n)return flow-lv;

                if(lv==0) break;

            }

            if(d[v]<mind)mind=d[v];//找出与pos相连的点的最小标号

        }

    }

    if(lv==flow)//没有找到增广路劲,进行标号更新

    {

        --gap[d[pos]];

        if(!gap[d[pos]])

            d[source]=n;

        d[pos]=mind+1;

        ++gap[d[pos]];

    }

    return flow-lv;

}

int sap(int st,int de)

{

    source=st;

    des=de;

    memset(d,0,sizeof(d));

    memset(gap,0,sizeof(gap));

    gap[0]=n;//初始标号为0的有n个.

    int ans=0;

    while(d[st]<n)//n是图中点的个数     {

        ans+=dfs(st,inf);

        //cout<<d[st]<<endl;

    }

    return ans;

}

void init()

{

    e=0;

    memset(index,-1,sizeof(index));

}

int main()

{

    while(scanf("%d%d",&m,&n)!=EOF)

    {

        init();

        int i;

        int ll,rr,cap;

        for(i=0;i<m;i++)

        {

            scanf("%d%d%d",&ll,&rr,&cap);

            addedge(ll,rr,cap);

        }

        printf("%d\n",sap(1,n));     }

    return 0;

}

 非递归版sap:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

#define Maxn 6010

#define Maxm 200000

#define LL __int64

#define Abs(a) (a)>0?(a):(-a)

using namespace std;

struct Edge{

    int from,to,next;

    LL val;

}edge[Maxm];

int index[Maxn],d[Maxn],gap[Maxn],e,vi[Maxn],n,m;

LL value[Maxn];

LL inf=0;

inline void addedge(int from,int to,LL val)//有向边

{

    edge[e].from=from;

    edge[e].to=to;

    edge[e].val=val;

    edge[e].next=index[from];

    index[from]=e++;

    edge[e].from=to;

    edge[e].to=from;

    edge[e].val=0;

    edge[e].next=index[to];

    index[to]=e++;

}

int prev[Maxn],curr[Maxn];

LL sap(int src,int des,int N)//分别为起点源点和点的数目

{

    bool flag;

    int u=src;

    LL cnt=inf,sum=0;

    memset(d,0,sizeof(d));

    memset(gap,0,sizeof(gap)); gap[0]=N;

    

    while(d[src]!=N)

    {

        flag=false;

        for(int i=index[u];i!=-1;i=edge[i].next)

        {

            if(edge[i].val&&d[edge[i].to]==d[u]-1)

            {

                cnt=min(cnt,edge[i].val);

                prev[edge[i].to]=u;

                curr[edge[i].to]=i;

                u=edge[i].to;

                

                flag=true;

                if(u==des)

                {

                    while(u!=src)

                    {

                        edge[curr[u]].val-=cnt;

                        edge[curr[u]^1].val+=cnt;

                        u=prev[u];

                    }

                    sum+=cnt;

                    cnt=inf;

                }

                else break;

            }

        }

        if(!flag)

        {

            if(!--gap[d[u]]) break;

            else

            {

                d[u]=N;

                for(int i=index[u];i!=-1;i=edge[i].next)

                {

                    if(edge[i].val) d[u]=min(d[u],d[edge[i].to]+1);

                }

                gap[d[u]]++;

                if(u!=src) u=prev[u];

            }

        }

    }

    return sum;

}

void init()

{

    e=0;

    inf=0;

    memset(index,-1,sizeof(index));

    memset(vi,0,sizeof(vi));

}

 

你可能感兴趣的:(SAP)