SAP 网络流模板,邻接矩阵

来源:互联网 发布:java内嵌webkit浏览器 编辑:程序博客网 时间:2024/04/30 21:27

转自:http://www.cnblogs.com/wally/archive/2013/05/03/3054778.html

#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAXN 222#define inf 100000000+1000int map[MAXN][MAXN];//存图int pre[MAXN];//记录当前点的前驱int level[MAXN];//记录距离标号int gap[MAXN];//gap常数优化int NV,NE;//入口参数vs源点,vt汇点int SAP(int vs,int vt){    memset(pre,-1,sizeof(pre));    memset(level,0,sizeof(level));    memset(gap,0,sizeof(gap));     gap[0]=vt;    int v,u=pre[vs]=vs,maxflow=0,aug=inf;    while(level[vs]<vt){        //寻找可行弧        for(v=1;v<=vt;v++){            if(map[u][v]>0&&level[u]==level[v]+1){                break;            }        }        if(v<=vt){            pre[v]=u;            u=v;            if(v==vt){                aug=inf;                //寻找当前找到的一条路径上的最大流                  for(int i=v;i!=vs;i=pre[i]){                    if(aug>map[pre[i]][i])aug=map[pre[i]][i];                }                maxflow+=aug;                //更新残留网络                for(int i=v;i!=vs;i=pre[i]){                    map[pre[i]][i]-=aug;                    map[i][pre[i]]+=aug;                }                u=vs;//从源点开始继续搜            }        }else {            //找不到可行弧            int minlevel=vt;            //寻找与当前点相连接的点中最小的距离标号            for(v=1;v<=vt;v++){                if(map[u][v]>0&&minlevel>level[v]){                    minlevel=level[v];                }            }            gap[level[u]]--;//(更新gap数组)当前标号的数目减1;            if(gap[level[u]]==0)break;//出现断层            level[u]=minlevel+1;            gap[level[u]]++;            u=pre[u];        }    }    return maxflow;}int main(){    int n,m,u,v,cap;    while(~scanf("%d%d",&m,&n)){        memset(map,0,sizeof(map));        for(int i=1;i<=m;i++){            scanf("%d%d%d",&u,&v,&cap);            map[u][v]+=cap;        }        printf("%d\n",SAP(1,n));    }    return 0;}


2 0