最大流sap模板 (转自庄神)

最大流sap模板 

转自庄神:Orz zsO  

以后就用它了 好高兴。。。233333

http://www.zlinkin.com/?p=34

typedef  struct {
    int v, next, val;
} edge;
const int MAXN = 20010;
const int MAXM = 500010;
 
edge e[MAXM];
int p[MAXN], eid;
 
inline void init() {
    memset(p, -1, sizeof(p));
    eid = 0;
}
 
//有向
inline void insert1(int from, int to, int val) {
    e[eid].v = to;
    e[eid].val = val;
    e[eid].next = p[from];
    p[from] = eid++;
 
    swap(from, to);
 
    e[eid].v = to;
    e[eid].val = 0;
    e[eid].next = p[from];
    p[from] = eid++;
}
 
//无向
inline void insert2(int from, int to, int val) {
    e[eid].v = to;
    e[eid].val = val;
    e[eid].next = p[from];
    p[from] = eid++;
 
    swap(from, to);
 
    e[eid].v = to;
    e[eid].val = val;
    e[eid].next = p[from];
    p[from] = eid++;
}
 
int n, m; //n为点数 m为边数
int h[MAXN];
int gap[MAXN];
 
int source, sink;
inline int dfs(int pos, int cost) {
    if (pos == sink) {
        return cost;
    }
 
    int j, minh = n - 1, lv = cost, d;
 
    for (j = p[pos]; j != -1; j = e[j].next) {
        int v = e[j].v, val = e[j].val;
 
        if(val > 0) {
            if (h[v] + 1 == h[pos]) {
                if (lv < e[j].val) {
                    d = lv;
                } else {
                    d = e[j].val;
                }
 
                d = dfs(v, d);
                e[j].val -= d;
                e[j ^ 1].val += d;
                lv -= d;
 
                if (h[source] >= n) {
                    return cost - lv;
                }
 
                if (lv == 0) {
                    break;
                }
            }
 
            if (h[v] < minh)	{
                minh = h[v];
            }
        }
    }
 
    if (lv == cost) {
        --gap[h[pos]];
 
        if (gap[h[pos]] == 0) {
            h[source] = n;
        }
 
        h[pos] = minh + 1;
        ++gap[h[pos]];
    }
 
    return cost - lv;
 
}
 
int sap(int st, int ed) {
 
    source = st;
    sink = ed;
    int ret = 0;
    memset(gap, 0, sizeof(gap));
    memset(h, 0, sizeof(h));
 
    //gap[st] = n;
    gap[0] = n;
 
    while (h[st] < n) {
        ret += dfs(st, INT_MAX);
    }
 
    return ret;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值