最大流模板

残北

关注

阅读 28

2022-05-05

最高标号预留推进算法(HLPP)

template <class Cap> struct HLPP {
    struct Edge {
        int v, rev;
        Cap cap;
        Edge(int _v, Cap c, int _rev): v(_v), rev(_rev), cap(c) {}
    };
    vector<Cap> exflow;
    vector<int> h;
    vector<int> cnt;
    int ht, n, s, t, labelcnt;
    vector<vector<Edge> > G;
    vector<vector<int> > hq;
    void init(int n) {
        this->n = n;
        ht = labelcnt = 0;
        G.resize(n + 1);
        for (int i = 0; i <= n; ++i) G[i].clear();
    }
    void AddEdge(int from, int to, Cap cap) {
        G[from].emplace_back(to, cap, G[to].size());
        G[to].emplace_back(from, 0, G[from].size() - 1);
    }
    void Update(int u, int newh) {
        ++labelcnt;
        if (h[u] != n + 1) --cnt[h[u]];
        h[u] = newh;
        if (newh == n + 1) return;
        ++cnt[ht = newh];
        if (exflow[u] > 0) hq[newh].push_back(u);
    }
    void GlobalRelabel() {
        queue<int> Q;
        hq.assign(n + 2, vector<int>(0));
        h.assign(n + 1, n + 1);
        cnt.assign(n + 1, 0);
        Q.push(t);
        labelcnt = ht = h[t] = 0;
        while (!Q.empty()) {
            int u = Q.front();
            Q.pop();
            for (Edge& e : G[u]) {
                if (h[e.v] == n + 1 && G[e.v][e.rev].cap) {
                    Update(e.v, h[u] + 1);
                    Q.push(e.v);
                }
            }
            ht = h[u];
        }
    }
    void Push(int u, Edge& e) {
        if (exflow[e.v] == 0) hq[h[e.v]].push_back(e.v);
        Cap df = min(exflow[u], e.cap);
        e.cap -= df;
        G[e.v][e.rev].cap += df;
        exflow[u] -= df;
        exflow[e.v] += df;
    }
    void Discharge(int u) {
        int nxth = n + 1;
        for (Edge& e : G[u]) {
            if (e.cap) {
                if (h[u] == h[e.v] + 1) {
                    Push(u, e);
                    if (exflow[u] <= 0) return;
                } else nxth = min(nxth, h[e.v] + 1);
            }
        }
        if (cnt[h[u]] > 1) Update(u, nxth);
        else {
            for (; ht >= h[u]; hq[ht--].clear()) {
                for (int& j : hq[ht]) Update(j, n + 1);
            }
        }
    }
    Cap MaxFlow(int s, int t) {
        this->s = s;
        this->t = t;
        exflow.assign(n + 1, 0);
        Cap INF = numeric_limits<Cap>::max();
        exflow[s] = INF;
        exflow[t] = -INF;
        GlobalRelabel();
        for (Edge& e : G[s]) Push(s, e);
        for (; ht >= 0; --ht) {
            while (!hq[ht].empty()) {
                int u = hq[ht].back();
                hq[ht].pop_back();
                Discharge(u);
                if (labelcnt > (n << 2)) GlobalRelabel();
            }
        }
        return exflow[t] + INF;
    }
};

Dinic 算法

template <class Cap> struct Dinic {
	struct Edge {
		int from, to;
		Cap cap, flow;
		Edge(int u, int v, Cap c, Cap f): from(u), to(v), cap(c), flow(f) {}
	};
	int n, m, s, t;
	vector<Edge> edges;
	vector<vector<int> > G;
	vector<bool> vis;
	vector<int> d;
	vector<int> cur;
	void init(int n) {
	    this->n = n;
		G.assign(n + 1, vector<int>(0));
		edges.clear();
	}
	void AddEdge(int from, int to, Cap cap) {
		edges.emplace_back(from, to, cap, 0);
		edges.emplace_back(to, from, 0, 0);
		m = edges.size();
		G[from].push_back(m - 2);
		G[to].push_back(m - 1);
	}
	bool BFS() {
		vis.assign(n + 1, 0);
		d.assign(n + 1, 0);
		queue<int> Q;
		Q.push(s);
		d[s] = 0;
		vis[s] = 1;
		while (!Q.empty()) {
			int x = Q.front();
			Q.pop();
			for (int i = 0; i < G[x].size(); ++i) {
				Edge& e = edges[G[x][i]];
				if (!vis[e.to] && e.cap > e.flow) {
					vis[e.to] = 1;
					d[e.to] = d[x] + 1;
					Q.push(e.to);
				}
			}
		}
		return vis[t];
	}
	Cap DFS(int x, Cap a) {
	    if (x == t || a == 0) return a;
	    Cap flow = 0, f;
	    for (int& i = cur[x]; i < G[x].size(); ++i) {
            Edge& e = edges[G[x][i]];
            if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
                e.flow += f;
                edges[G[x][i] ^ 1].flow -= f;
                flow += f;
                a -= f;
                if (a == 0) break;
            }
	    }
	    return flow;
	}
	Cap MaxFlow(int s, int t) {
		this->s = s;
		this->t = t;
		Cap flow = 0;
		Cap INF = numeric_limits<Cap>::max();
		while (BFS()) {
			cur.assign(n + 1, 0);
			flow += DFS(s, INF);
		}
		return flow;
	}
};

ISAP 算法(Improved Shortest Augmenting Path)

template <class Cap> struct ISAP {
    struct Edge {
		int from, to;
		Cap cap, flow;
		Edge(int u, int v, Cap c, Cap f): from(u), to(v), cap(c), flow(f) {}
	};
    int n, m, s, t;
    vector<Edge> edges;
    vector<vector<int> > G;
    vector<bool> vis;
	vector<int> d;
	vector<int> cur;
	vector<int> p;
	vector<int> num;
	void init(int n) {
        this->n = n + 1;
        G.assign(n + 1, vector<int>(0));
        edges.clear();
    }
    void AddEdge(int from, int to, Cap cap) {
        edges.emplace_back(from, to, cap, 0);
		edges.emplace_back(to, from, 0, 0);
        m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
    }
    bool BFS() {
        vis.assign(n + 1, 0);
        d.assign(n + 1, 0);
        queue<int> Q;
        Q.push(t);
        vis[t] = 1;
        d[t] = 0;
        while (!Q.empty()) {
            int x = Q.front();
            Q.pop();
            for (int i = 0; i < G[x].size(); ++i) {
                Edge &e = edges[G[x][i] ^ 1];
                if (!vis[e.from] && e.cap > e.flow) {
                    vis[e.from] = 1;
                    d[e.from] = d[x] + 1;
                    Q.push(e.from);
                }
            }
        }
        return vis[s];
    }
    Cap Augment() {
        int x = t;
        Cap a = numeric_limits<Cap>::max();
        while (x != s) {
            Edge &e = edges[p[x]];
            a = min(a, e.cap - e.flow);
            x = edges[p[x]].from;
        }
        x = t;
        while (x != s) {
            edges[p[x]].flow += a;
            edges[p[x] ^ 1].flow -= a;
            x = edges[p[x]].from;
        }
        return a;
    }
    Cap MaxFlow(int s, int t) {
    	this->s = s;
    	this->t = t;
        p.assign(n + 1, 0);
        Cap flow = 0;
        BFS();
        num.assign(n + 1, 0);
        for (int i = 0; i < n; ++i) num[d[i]]++;
        int x = s;
        cur.assign(n + 1, 0);
        while (d[s] <= n - 1) {
            if (x == t) {
                flow += Augment();
                x = s;
            }
            int ok = 0;
            for (int i = cur[x]; i < G[x].size(); ++i) {
                Edge &e = edges[G[x][i]];
                if (e.cap > e.flow && d[x] == d[e.to] + 1) {
                    ok = 1;
                    p[e.to] = G[x][i];
                    cur[x] = i;
                    x = e.to;
                    break;
                }
            }
            if (!ok) {
                int M = n - 1;
                for (int i = 0; i < G[x].size(); ++i) {
                    Edge &e = edges[G[x][i]];
                    if (e.cap > e.flow) M = min(M, d[e.to]);
                }
                if (--num[d[x]] == 0) break;
                num[d[x] = M + 1]++;
                cur[x] = 0;
                if (x != s) x = edges[p[x]].from;
            }
        }
        return flow;
    }
};

Edmons-Karp 算法

template <class Cap> struct EdmonsKarp {
	struct Edge {
		int from, to;
		Cap cap, flow;
		Edge(int u, int v, Cap c, Cap f): from(u), to(v), cap(c), flow(f) {}
	};
	int n, m, s, t;
	vector<Edge> edges;
	vector<vector<int> > G;
	vector<Cap> a;
	vector<int> p;
	void init(int n) {
	    this->n = n;
		G.assign(n + 1, vector<int>(0));
		edges.clear();
	}
	void AddEdge(int from, int to, Cap cap) {
		edges.emplace_back(from, to, cap, 0);
		edges.emplace_back(to, from, 0, 0);
		m = edges.size();
		G[from].push_back(m - 2);
		G[to].push_back(m - 1);
	}
	bool BFS() {
		queue<int> Q;
		a.assign(n + 1, 0);
		Q.push(s);
		a[s] = numeric_limits<Cap>::max();
		while (!Q.empty()) {
			int x = Q.front();
			Q.pop();
			for (int i = 0; i < G[x].size(); ++i) {
				Edge& e = edges[G[x][i]];
				if (!a[e.to] && e.cap > e.flow) {
					p[e.to] = G[x][i];
					a[e.to] = min(a[x], e.cap - e.flow);
					Q.push(e.to);
				}
			}
			if (a[t]) return true;
		}
		return false;
	}
	Cap MaxFlow(int s, int t) {
		this->s = s;
		this->t = t;
		p.assign(n + 1, 0);
		Cap flow = 0;
		while (BFS()) {
			for (int u = t; u != s; u = edges[p[u]].from) {
				edges[p[u]].flow += a[t];
				edges[p[u] ^ 1].flow -= a[t];
			}
			flow += a[t];
		}
		return flow;
	}
};

精彩评论(0)

0 0 举报