Advertisement
Dang_Quan_10_Tin

Hugarian

Nov 8th, 2020 (edited)
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.33 KB | None | 0 0
  1. // start from 0
  2. struct PerfectMatchingMinCost
  3. {
  4.     typedef vector<int> VI;
  5.     typedef vector<VI> VII;
  6.     typedef vector<ll> VD;
  7.     const ll INF = 1e18;
  8.  
  9.     int N;
  10.     VII adj;
  11.     VI mx, my, arg, trace;
  12.     VD d, fx, fy;
  13.     vector<VD> cost;
  14.  
  15.     queue<int> q;
  16.  
  17.     ll getCost(int x, int y)
  18.     {
  19.         return cost[x][y] - fx[x] - fy[y];
  20.     }
  21.  
  22.     void initBFS(int start)
  23.     {
  24.         for (int i = 0; i < N; i++)
  25.             trace[i] = -1;
  26.         while (!q.empty())
  27.             q.pop();
  28.         q.push(start);
  29.         for (int i = 0; i < N; i++)
  30.             d[i] = getCost(start, i), arg[i] = start;
  31.     }
  32.  
  33.     int findPath()
  34.     {
  35.         while (!q.empty())
  36.         {
  37.             int x = q.front();
  38.             q.pop();
  39.             for (int i = 0; i < (int)adj[x].size(); i++)
  40.             {
  41.                 int y = adj[x][i];
  42.                 if (trace[y] == -1)
  43.                 {
  44.                     ll w = getCost(x, y);
  45.                     if (w == 0)
  46.                     {
  47.                         trace[y] = x;
  48.                         if (my[y] == -1)
  49.                             return y;
  50.                         q.push(my[y]);
  51.                     }
  52.                     if (d[y] > w)
  53.                     {
  54.                         d[y] = w;
  55.                         arg[y] = x;
  56.                     }
  57.                 }
  58.             }
  59.         }
  60.         return -1;
  61.     }
  62.  
  63.     int update(int start)
  64.     {
  65.         ll delta = INF;
  66.         for (int y = 0; y < N; y++)
  67.             if (trace[y] == -1)
  68.                 delta = min(delta, d[y]);
  69.         fx[start] += delta;
  70.         for (int y = 0; y < N; y++)
  71.             if (trace[y] != -1)
  72.             {
  73.                 int x = my[y];
  74.                 fx[x] += delta;
  75.                 fy[y] -= delta;
  76.             }
  77.             else
  78.                 d[y] -= delta;
  79.         for (int y = 0; y < N; y++)
  80.             if (trace[y] == -1 && d[y] == 0)
  81.             {
  82.                 trace[y] = arg[y];
  83.                 if (my[y] == -1)
  84.                     return y;
  85.                 q.push(my[y]);
  86.             }
  87.         return -1;
  88.     }
  89.  
  90.     void enlarge(int finish)
  91.     {
  92.         for (int y = finish; y != -1;)
  93.         {
  94.             int x = trace[y];
  95.             int yy = mx[x];
  96.             mx[x] = y;
  97.             my[y] = x;
  98.             y = yy;
  99.         }
  100.     }
  101.     PerfectMatchingMinCost(int n = 0)
  102.     {
  103.         N = n;
  104.         cost = vector<VD>(n, VD(n, INF));
  105.         adj = VII(n);
  106.         trace = VI(n);
  107.         arg = VI(n);
  108.         fx = VD(n, -INF);
  109.         fy = VD(n);
  110.         d = VD(n);
  111.         mx = VI(n, -1);
  112.         my = VI(n, -1);
  113.     }
  114.  
  115.     void AddEdge(int x, int y, ll c)
  116.     {
  117.         if (cost[x][y] == INF)
  118.             adj[x].push_back(y);
  119.         if (cost[x][y] > c)
  120.             cost[x][y] = c;
  121.     }
  122.  
  123.     ll GetMinCost()
  124.     {
  125.         for (int x = 0; x < N; x++)
  126.         {
  127.             initBFS(x);
  128.             int finish = -1;
  129.             do
  130.             {
  131.                 finish = findPath();
  132.                 if (finish != -1)
  133.                     break;
  134.                 finish = update(x);
  135.             } while (finish == -1);
  136.             enlarge(finish);
  137.         }
  138.         ll ret = 0;
  139.         for (int x = 0; x < N; x++)
  140.             ret += cost[x][mx[x]] == INF ? 0 : cost[x][mx[x]];
  141.         return ret;
  142.     }
  143. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement