Advertisement
Dang_Quan_10_Tin

FIFOPreFlow

Dec 4th, 2021 (edited)
357
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.13 KB | None | 0 0
  1. //start from 0
  2. struct TEdge
  3. {
  4.     int x, y;
  5.     ll cf;
  6.     TEdge(int x = 0, int y = 0, ll cf = 0) : x(x), y(y), cf(cf) {}
  7. };
  8. struct FIFOPreFlow
  9. {
  10.     const ll inftyFlow = 1e17;
  11.     int n, s, t;
  12.     vector<TEdge> e;
  13.     vector<vector<int>> L;
  14.     vector<vector<int>::iterator> current;
  15.     vector<int> h;
  16.     vector<ll> excess;
  17.     queue<int> OverflowQueue;
  18.     vector<bool> InQueue;
  19.     ll FlowVal;
  20.  
  21.     PreFlow(int n = 0)
  22.     {
  23.         this->n = n;
  24.         L.resize(n + 2);
  25.         h.resize(n + 2);
  26.         excess.resize(n + 2);
  27.         InQueue.resize(n + 2);
  28.         current.resize(n + 2);
  29.         FlowVal = 0;
  30.     }
  31.  
  32.     void AddEdge(int u, int v, ll c)
  33.     {
  34.         e.emplace_back(u, v, c);
  35.         L[u].emplace_back(e.size() - 1);
  36.         e.emplace_back(v, u, 0);
  37.         L[v].emplace_back(e.size() - 1);
  38.     }
  39.  
  40.     void BFS(int Finish)
  41.     {
  42.         queue<int> q;
  43.         q.push(Finish);
  44.         while (!q.empty())
  45.         {
  46.             int u, v;
  47.             u = q.front();
  48.             q.pop();
  49.             for (int i : L[u])
  50.                 if (v = e[i].y, e[i ^ 1].cf > 0 && h[v] == 2 * n - 1)
  51.                 {
  52.                     h[v] = h[u] + 1;
  53.                     q.push(v);
  54.                 }
  55.         }
  56.     }
  57.     void GlobalRelabel()
  58.     {
  59.         fill(h.begin(), h.end(), 2 * n - 1);
  60.         h[t] = 0;
  61.         BFS(t);
  62.         h[s] = n;
  63.         BFS(s);
  64.         for (int u = 0; u < n; ++u)
  65.             current[u] = L[u].begin();
  66.     }
  67.     inline bool Overflow(int u)
  68.     {
  69.         return u != s && u != t && excess[u] > 0;
  70.     }
  71.     void Init()
  72.     {
  73.         fill(excess.begin(), excess.end(), 0);
  74.         for (int i : L[s])
  75.         {
  76.             ll fval = e[i].cf;
  77.             e[i].cf -= fval;
  78.             e[i ^ 1].cf += fval;
  79.             excess[s] -= fval;
  80.             excess[e[i].y] += fval;
  81.         }
  82.         GlobalRelabel();
  83.  
  84.         fill(InQueue.begin(), InQueue.end(), false);
  85.         for (int u = 0; u < n; ++u)
  86.             if (Overflow(u))
  87.             {
  88.                 OverflowQueue.push(u);
  89.                 InQueue[u] = true;
  90.             }
  91.     }
  92.     void Push(int i)
  93.     {
  94.         int u = e[i].x, v = e[i].y;
  95.         ll Delta = min(excess[u], e[i].cf);
  96.         e[i].cf -= Delta;
  97.         e[i ^ 1].cf += Delta;
  98.         excess[u] -= Delta;
  99.         excess[v] += Delta;
  100.     }
  101.     void Lift(int u)
  102.     {
  103.         h[u] = 2 * n - 1;
  104.         for (int i : L[u])
  105.             if (e[i].cf > 0)
  106.                 h[u] = min(h[u], h[e[i].y]);
  107.         ++h[u];
  108.     }
  109.     inline int PopFromQueue()
  110.     {
  111.         int u = OverflowQueue.front();
  112.         OverflowQueue.pop();
  113.         InQueue[u] = false;
  114.         return u;
  115.     }
  116.     inline void PushToQueue(int u)
  117.     {
  118.         if (InQueue[u])
  119.             return;
  120.         OverflowQueue.push(u);
  121.         InQueue[u] = true;
  122.     }
  123.     void FifoPreflowPush()
  124.     {
  125.         int LiftCnt = 0;
  126.         while (!OverflowQueue.empty())
  127.         {
  128.             int u = PopFromQueue();
  129.             for (; excess[u] > 0 && current[u] != L[u].end(); ++current[u])
  130.             {
  131.                 int i = *current[u];
  132.                 int v = e[i].y;
  133.                 if (e[i].cf > 0 && h[u] > h[v])
  134.                 {
  135.                     Push(i);
  136.                     if (Overflow(v))
  137.                         PushToQueue(v);
  138.                 }
  139.             }
  140.             if (excess[u] > 0)
  141.             {
  142.                 if (LiftCnt == n)
  143.                 {
  144.                     GlobalRelabel();
  145.                     LiftCnt = 0;
  146.                 }
  147.                 else
  148.                 {
  149.                     Lift(u);
  150.                     ++LiftCnt;
  151.                     current[u] = L[u].begin();
  152.                 }
  153.                 PushToQueue(u);
  154.             }
  155.         }
  156.     }
  157.  
  158.     ll MaxFlow(int s, int t)
  159.     {
  160.         this->s = s;
  161.         this->t = t;
  162.  
  163.         Init();
  164.         FifoPreflowPush();
  165.  
  166.         for (int i = 0; i < (int)e.size(); i += 2)
  167.         {
  168.             if (e[i].x == s)
  169.                 FlowVal += e[i ^ 1].cf;
  170.             if (e[i].y == s)
  171.                 FlowVal -= e[i ^ 1].cf;
  172.         }
  173.  
  174.         return FlowVal;
  175.     }
  176. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement