POJ 1273 第一个SAP(ISAP)

/* sap学了很长时间,一直不敢下手写,结果就是不写永远不会真正的理解算法的含义,sap理论很多算法书上都有讲解,但我还是建议看数学专业 图论的书,比如 《有向图的理论,算法及应用》,这本书的内容非常棒,相信看过的都知道吧,比其他算法书上讲的透多了。
SAP有个优化就是 当出现断链时,就可以直接退出,还有个优化是当前弧的优化,这两个优化只需要一句话+一个数组就解决了,相当实惠,好的ISAP执行的效率真的非常高,我写的ISAP用的是链式前向星法表示。
这个就算是模板了吧,虽然写的不是很好。。*/

#include<iostream>
#include<cstdio>
#include<memory.h>
#include<cmath>
using namespace std;

#define MAXN 500
#define MAXE 40000
#define INF 0x7fffffff

long ne,nv,tmp,s,t,index;

struct Edge{
    long next,pair;
    long v,cap,flow;
}edge[MAXE];
long net[MAXN];
long ISAP()
{
    long numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN];
    long cur_flow,max_flow,u,tmp,neck,i;
    memset(dist,0,sizeof(dist));
    memset(numb,0,sizeof(numb));
    memset(pre,-1,sizeof(pre));
    for(i = 1 ; i <= nv ; ++i)
        curedge[i] = net[i];
    numb[nv] = nv;
    max_flow = 0;
    u = s;
    while(dist[s] < nv)
    {
        /* first , check if has augmemt flow */
        if(u == t)
        {
            cur_flow = INF;
            for(i = s; i != t;i = edge[curedge[i]].v) 
            {  
                if(cur_flow > edge[curedge[i]].cap)
                {
                    neck = i;
                    cur_flow = edge[curedge[i]].cap;
                }
            }
            for(i = s; i != t; i = edge[curedge[i]].v)
            {
                tmp = curedge[i];
                edge[tmp].cap -= cur_flow;
                edge[tmp].flow += cur_flow;
                tmp = edge[tmp].pair;
                edge[tmp].cap += cur_flow;
                edge[tmp].flow -= cur_flow;
            }
            max_flow += cur_flow;
            u = neck;
        }
        /* if .... else ... */
        for(i = curedge[u]; i != -1; i = edge[i].next)
            if(edge[i].cap > 0 && dist[u] == dist[edge[i].v]+1)
                break;
        if(i != -1)
        {
            curedge[u] = i;
            pre[edge[i].v] = u;
            u = edge[i].v;
        }else{
            if(0 == --numb[dist[u]]) break;
            curedge[u] = net[u];
            for(tmp = nv,i = net[u]; i != -1; i = edge[i].next)
                if(edge[i].cap > 0)
                    tmp = tmp<dist[edge[i].v]?tmp:dist[edge[i].v];
            dist[u] = tmp + 1;
            ++numb[dist[u]];
            if(u != s) u = pre[u];
        }
    }
    
    return max_flow;
}
int main() {
    long i,j,np,nc,m,n;
    long a,b,val;
    long g[MAXN][MAXN];
    while(scanf("%d%d",&ne,&nv)!=EOF)
    {
        s = 1;
        t = nv;
        memset(g,0,sizeof(g));
        memset(net,-1,sizeof(net));
        for(i=0;i<ne;++i)
        {
            scanf("%ld%ld%ld",&a,&b,&val);
            g[a][b] += val;
         }
         for(i=1;i<=nv;++i)
             for(j = i; j <= nv;++j)
                 if(g[i][j]||g[j][i])
                 {
                     edge[index].next = net[i];
                     edge[index].v = j;
                     edge[index].cap = g[i][j];
                     edge[index].flow = 0;
                     edge[index].pair = index+1;
                     net[i] = index++;
                     edge[index].next = net[j];
                     edge[index].v = i;
                     edge[index].cap = g[j][i];
                     edge[index].flow = 0;
                     edge[index].pair = index-1;
                     net[j] = index++;
                 }
        printf("%ld\n",ISAP());
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lvpengms/p/1662738.html