最大流sap

带当前弧优化 gap优化的sap 甚至省去了开始的bfs分层

虽然花了一些时间了解原理 但是感觉不亏 现在能完全独立靠原理写出具体实现了

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1007, maxm = 10007, inf = 0x3f3f3f3f;
int st, ed, tot, n, m;
struct Edge{
    int u, v, nxt, w, f;
    Edge(){}
    Edge(int u, int v, int nxt, int w, int f):u(u), v(v), nxt(nxt), w(w), f(f){}
}edge[maxm];
int head[maxn], cur[maxn], gap[maxn], dep[maxn], pre[maxn];
void init(){
    tot = 0;
    memset(head, -1, sizeof head);
}
void addedge(int u, int v, int w){
    edge[tot] = Edge(u, v, head[u], w, 0);
    head[u] = tot++;
    edge[tot] = Edge(v, u, head[v], 0, 0);
    head[v] = tot++;
}
int sap(){
    memset(gap, 0, sizeof (gap));
    memset(dep, 0, sizeof (dep));
    memcpy(cur, head, sizeof (head));
    int u = st;
    pre[u] = -1;
    gap[0] = n;
    int ans = 0;
    while(dep[st] < n){
        if(u == ed){
            int MIN = inf;
            for(int i = pre[u]; i != -1; i = pre[edge[i].u]){
                if(MIN > edge[i].w - edge[i].f)
                    MIN = edge[i].w - edge[i].f;
            }
            for(int i = pre[u]; i != -1; i = pre[edge[i].u]){
                edge[i].f += MIN;
                edge[i^1].f -= MIN;
            }
            u = st;
            ans += MIN;
            continue;
        }
        bool flag = false;
        int v;
        for(int i = cur[u]; i != -1; i = edge[i].nxt){
            v = edge[i].v;
            if(edge[i].w - edge[i].f && dep[v]+1 == dep[u]){
                flag = true;
                cur[u] = pre[v] = i;
                break;
            }
        }
        if(flag){
            u = v;
            continue;
        }
        int MIN = n;
        for(int i = head[u]; i != -1; i = edge[i].nxt){
            if(edge[i].w - edge[i].f && dep[edge[i].v] < MIN){
                MIN = dep[edge[i].v];
                cur[u] = i;
            }
        }
        gap[dep[u]]--;
        if(!gap[dep[u]])
            return ans;
        dep[u] = MIN+1;
        gap[dep[u]]++;
        if(u != st)
            u = edge[pre[u]].u;
    }
    return ans;
}
int main(){
    int t, kase = 1;
    scanf("%d", &t);
    while(t--){
        init();
        scanf("%d%d", &n, &m);
        while(m--){
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            addedge(u, v, w);
        }
        st = 1, ed = n;
        printf("Case %d: ", kase++);
        printf("%d\n", sap());
    }
    return 0;
}
时间: 2024-11-15 00:41:59

最大流sap的相关文章

HDU3605Escape(最大流SAP+状态压缩优化点的个数)

Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6239    Accepted Submission(s): 1474 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient

HDU 3277 Marriage Match III(拆点+二分+最大流SAP)

这个题目是说,有n个女的和男的找伴侣.然后女的具有主动选择权,每个女的可以选自己喜欢的男的,也可以挑选k个不喜欢的男的,做法就是:把女的拆点,u1->u2建立一条容量为k的边.如果遇见喜欢的男生i->j+2*n建一条容量为1的边,否则i+n->j+2*n建一条容量为1的边.最后将源点和女生相连容量为mid,汇点与男生相连容量为mid.枚举mid,看是否会产生满流. 可能姿势不够优美dinic超时了啊,换成SAP快了很多啊... Marriage Match III Time Limit:

HDU2732Leapin&amp;#39; Lizards(最大流SAP,建图---折点法)

Leapin' Lizards Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1531    Accepted Submission(s): 623 Problem Description Your platoon of wandering lizards has entered a strange room in the labyr

HDU2732Leapin&#39; Lizards(最大流SAP,建图---折点法)

Leapin' Lizards Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1531    Accepted Submission(s): 623 Problem Description Your platoon of wandering lizards has entered a strange room in the labyr

M - Escape - HDU 3605 - (缩点+最大流SAP)

题目大意:2012世界末日来了,科学家发现了一些星球可以转移人口,不过有的人可以在一些星球上生存有的人不行,而且每个星球都有一定的承载量,现在想知道是否所有的人都可以安全转移呢? 输入:首先输入一个N和M,表示人数和星球数,接着输入N行,每行有M个01组成的数,0表示第Ni个人无法再Mj号星球上生存,1表示可以生存,最后一行是每个星球的最大承载量. 分析:刚看的时候是一道比较裸的最大流题目,只要求出来最大流是否等于总人口数就行了,不过人的数量貌似是有点多的,刚开始没有管那么多直接上了最大流,不过

HDU 3998 Sequence (最长递增子序列+最大流SAP,拆点法)经典

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1666    Accepted Submission(s): 614 Problem Description There is a sequence X (i.e. x[1], x[2], ..., x[n]). We define increasing subsequ

HDU3081Marriage Match II(二分答案+并查集+最大流SAP)经典

Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2507    Accepted Submission(s): 856 Problem Description Presumably, you all have known the question of stable marriage match. A

网络流(三)----最大流SAP算法

以  HDU 3572  Task Schedule 为例的模板 Code: #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <stack>

HDU 4183 Pahom on Water(最大流SAP)

Pahom on Water Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 629    Accepted Submission(s): 288 Problem Description Pahom on Water is an interactive computer game inspired by a short story of

HDU3416 Marriage Match IV(spfa+最大流SAP)

Marriage Match IV Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2391    Accepted Submission(s): 722 Problem Description Do not sincere non-interference. Like that show, now starvae also take