首页 > 代码库 > 最大流ISAP算法模板

最大流ISAP算法模板

这两天学习了最大流,下面是ISAP算法模板:

const int inf = 0x3fffffff;
template <int N, int M>
struct Isap
{
    int top;
    int d[N], pre[N], cur[N], gap[N];
    struct Vertex{
        int head;
    } V[N];
    struct Edge{
        int v, next;
        int c, f;
    } E[M];
    void init(){
        memset(V, -1, sizeof(V));
        top = 0;
    }
    void add_edge(int u, int v, int c){
        E[top].v = v;
        E[top].c = c;
        E[top].f = 0;
        E[top].next = V[u].head;
        V[u].head = top++;
    }
    void add(int u,int v, int c){
        add_edge(u, v, c);
        add_edge(v, u, 0);
    }
    void set_d(int t){
        queue<int> Q;
        memset(d, -1, sizeof(d));
        memset(gap, 0, sizeof(gap));
        d[t] = 0;
        Q.push(t);
        while(!Q.empty()) {
            int v = Q.front(); Q.pop();
            ++gap[d[v]];
            for(int i = V[v].head; ~i; i = E[i].next) {
                int u = E[i].v;
                if(d[u] == -1) {
                    d[u] = d[v] + 1;
                    Q.push(u);
                }
            }
        }
    }
    int sap(int s, int t, int num) {
        set_d(t);
        int ans = 0, u = s;
        int flow = inf;
        memcpy(cur, V, sizeof(V));
        while(d[s] < num) {
            int &i = cur[u];
            for(; ~i; i = E[i].next) {
                int v = E[i].v;
                if(E[i].c > E[i].f && d[u] == d[v] + 1) {
                    u = v;
                    pre[v] = i;
                    flow = min(flow, E[i].c - E[i].f);
                    if(u == t) {
                        while(u != s) {
                            int j = pre[u];
                            E[j].f += flow;
                            E[j^1].f -= flow;
                            u = E[j^1].v;
                        }
                        ans += flow;
                        flow = inf;
                    }
                    break;
                }
            }
            if(i == -1) {
                if(--gap[d[u]] == 0)
                    break;
                int dmin = num - 1;
                cur[u] = V[u].head;
                for(int j = V[u].head; ~j; j = E[j].next)
                    if(E[j].c > E[j].f)
                        dmin = min(dmin, d[E[j].v]);
                d[u] = dmin + 1;
                ++gap[d[u]];
                if(u != s)
                    u = E[pre[u] ^ 1].v;
            }
        }
        return ans;
    }
};
Isap<1000, 1000000> Sap;


调用方式:
Sap.init(); //建边前调用
Sap.add(u, v, c); //在u->v之间建一条容量为c的边
Sap.sap(s, t, num); //s为源点,t为汇点,num为边的数量