Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //start from 0
- struct TEdge
- {
- int x, y;
- ll cf;
- TEdge(int x = 0, int y = 0, ll cf = 0) : x(x), y(y), cf(cf) {}
- };
- struct FIFOPreFlow
- {
- const ll inftyFlow = 1e17;
- int n, s, t;
- vector<TEdge> e;
- vector<vector<int>> L;
- vector<vector<int>::iterator> current;
- vector<int> h;
- vector<ll> excess;
- queue<int> OverflowQueue;
- vector<bool> InQueue;
- ll FlowVal;
- PreFlow(int n = 0)
- {
- this->n = n;
- L.resize(n + 2);
- h.resize(n + 2);
- excess.resize(n + 2);
- InQueue.resize(n + 2);
- current.resize(n + 2);
- FlowVal = 0;
- }
- void AddEdge(int u, int v, ll c)
- {
- e.emplace_back(u, v, c);
- L[u].emplace_back(e.size() - 1);
- e.emplace_back(v, u, 0);
- L[v].emplace_back(e.size() - 1);
- }
- void BFS(int Finish)
- {
- queue<int> q;
- q.push(Finish);
- while (!q.empty())
- {
- int u, v;
- u = q.front();
- q.pop();
- for (int i : L[u])
- if (v = e[i].y, e[i ^ 1].cf > 0 && h[v] == 2 * n - 1)
- {
- h[v] = h[u] + 1;
- q.push(v);
- }
- }
- }
- void GlobalRelabel()
- {
- fill(h.begin(), h.end(), 2 * n - 1);
- h[t] = 0;
- BFS(t);
- h[s] = n;
- BFS(s);
- for (int u = 0; u < n; ++u)
- current[u] = L[u].begin();
- }
- inline bool Overflow(int u)
- {
- return u != s && u != t && excess[u] > 0;
- }
- void Init()
- {
- fill(excess.begin(), excess.end(), 0);
- for (int i : L[s])
- {
- ll fval = e[i].cf;
- e[i].cf -= fval;
- e[i ^ 1].cf += fval;
- excess[s] -= fval;
- excess[e[i].y] += fval;
- }
- GlobalRelabel();
- fill(InQueue.begin(), InQueue.end(), false);
- for (int u = 0; u < n; ++u)
- if (Overflow(u))
- {
- OverflowQueue.push(u);
- InQueue[u] = true;
- }
- }
- void Push(int i)
- {
- int u = e[i].x, v = e[i].y;
- ll Delta = min(excess[u], e[i].cf);
- e[i].cf -= Delta;
- e[i ^ 1].cf += Delta;
- excess[u] -= Delta;
- excess[v] += Delta;
- }
- void Lift(int u)
- {
- h[u] = 2 * n - 1;
- for (int i : L[u])
- if (e[i].cf > 0)
- h[u] = min(h[u], h[e[i].y]);
- ++h[u];
- }
- inline int PopFromQueue()
- {
- int u = OverflowQueue.front();
- OverflowQueue.pop();
- InQueue[u] = false;
- return u;
- }
- inline void PushToQueue(int u)
- {
- if (InQueue[u])
- return;
- OverflowQueue.push(u);
- InQueue[u] = true;
- }
- void FifoPreflowPush()
- {
- int LiftCnt = 0;
- while (!OverflowQueue.empty())
- {
- int u = PopFromQueue();
- for (; excess[u] > 0 && current[u] != L[u].end(); ++current[u])
- {
- int i = *current[u];
- int v = e[i].y;
- if (e[i].cf > 0 && h[u] > h[v])
- {
- Push(i);
- if (Overflow(v))
- PushToQueue(v);
- }
- }
- if (excess[u] > 0)
- {
- if (LiftCnt == n)
- {
- GlobalRelabel();
- LiftCnt = 0;
- }
- else
- {
- Lift(u);
- ++LiftCnt;
- current[u] = L[u].begin();
- }
- PushToQueue(u);
- }
- }
- }
- ll MaxFlow(int s, int t)
- {
- this->s = s;
- this->t = t;
- Init();
- FifoPreflowPush();
- for (int i = 0; i < (int)e.size(); i += 2)
- {
- if (e[i].x == s)
- FlowVal += e[i ^ 1].cf;
- if (e[i].y == s)
- FlowVal -= e[i ^ 1].cf;
- }
- return FlowVal;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement