Advertisement
dipBRUR

Hopcroft Karp Algorithm for Maximum Matching | Implementatio

Aug 8th, 2017
615
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.19 KB | None | 0 0
  1. /**
  2.  * Author                      : Dipu Kumar Mohanto (Dip)
  3.  *                               CSE, BRUR.
  4.  *                               Batch - 6
  5.  *
  6.  * Problem                     : Hopcroft Karp Algorithm for Maximum Matching | Implementation
  7.  * Algorithm                   : Hopcroft Karp Algorithm for Maximum Matching
  8.  * Complexity                  : O(sqrt(V) * E)
  9.  * Category                    : Graph Theory, Bipartite Maximum Matching
  10.  *
  11.  * Difficulty                  :
  12.  *
  13.  * Source                      : GeeksForGeeks
  14.  *
  15.  * Verdict                     : OK
  16.  *
  17.  * Date                        :
  18.  * E-mail                      : dipukumarmohanto1@gmail.com
  19. **/
  20.  
  21.  
  22. #include <bits/stdc++.h>
  23.  
  24. using namespace std;
  25.  
  26. #define VI                  vector <int>
  27. #define pb                  push_back
  28.  
  29. #define inf                 1 << 28
  30. #define NILL                0
  31.  
  32.  
  33. const int mx = 1e6+6;
  34.  
  35.  
  36. int m;             // no. of element's in left side
  37. int n;             // no. of element's in right side
  38.  
  39.  
  40. VI G[mx];
  41.  
  42. int pairU[mx];     // pairU[u] stores pair of u in matching where u
  43.                    // is a vertex on left side of Bipartite Graph.
  44.                    // If u doesn't have any pair, then pairU[u] is NILL
  45.  
  46. int pairV[mx];     // pairV[v] stores pair of v in matching. If v
  47.                    // doesn't have any pair, then pairU[v] is NILL
  48.  
  49. int dist[mx];      // dist[u] stores distance of left side vertices
  50.                    // dist[u] is one more than dist[u'] if u is next
  51.                    // to u'in augmenting path
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61. bool bfs()         // return's true if there is an augmenting
  62. {                  // path, else returns false
  63.     queue <int> PQ;
  64.  
  65.     // First layer of vertices (set distance as 0)
  66.     for (int u=1; u<=m; u++)
  67.     {
  68.         // if there is a free vertex, add it to queue
  69.         if (pairU[u] == NILL)
  70.         {
  71.             // u is not matched
  72.             dist[u] = NILL;
  73.  
  74.             PQ.push(u);
  75.         }
  76.  
  77.         // Else set distance as infinite so that this
  78.         // vertex is considered next time
  79.         else
  80.             dist[u] = inf;
  81.     }
  82.     // Initialize distance to NILL as infinite
  83.     dist[NILL] = inf;
  84.  
  85.     // Q is going to contain vertex of left side only
  86.     while (!PQ.empty())
  87.     {
  88.         // Dequeue a vertex
  89.         int u = PQ.front();
  90.         PQ.pop();
  91.  
  92.         // If this vertex is not NILL and can provide a shorter path
  93.         if (u != NILL && dist[u] < dist[NILL])
  94.         {
  95.             for (auto v : G[u])
  96.             {
  97.                 // If pair of v is not considered so far
  98.                 // (v, pairV[V]) is not yet explored edge.
  99.                 if (dist[pairV[v]] == inf)
  100.                 {
  101.                     dist[pairV[v]] = dist[u] + 1;
  102.  
  103.                     PQ.push(pairV[v]);
  104.                 }
  105.             }
  106.         }
  107.     }
  108.     // If we could come back to NIL using alternating path of distinct
  109.     // vertices then there is an augmenting path
  110.     if (dist[NILL] != inf)
  111.         return true;
  112.  
  113.     else
  114.         return false;
  115. }
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123. // Returns true if there is an augmenting path beginning with free vertex u
  124. bool dfs(int u)
  125. {
  126.     if (u != NILL)
  127.     {
  128.         for (auto v : G[u])
  129.         {
  130.             // Follow the distances set by BFS
  131.             if (dist[pairV[v]] == dist[u] + 1)
  132.             {
  133.                 // If dfs for pair of v also returns
  134.                 // true
  135.                 if (dfs(pairV[v]))
  136.                 {
  137.                     pairU[u] = v;
  138.                     pairV[v] = u;
  139.  
  140.                     return true;
  141.                 }
  142.             }
  143.         }
  144.         // If there is no augmenting path beginning with u.
  145.         dist[u] = inf;
  146.         return false;
  147.     }
  148.     return true;
  149. }
  150.  
  151.  
  152. int hopcropt_carp()
  153. {
  154.     int max_match = 0;
  155.  
  156.     // Keep updating the result while there is an
  157.     // augmenting path
  158.     while (bfs())
  159.     {
  160.         // Find a free vertex
  161.         for (int u=1; u<=m; u++)
  162.         {
  163.             // If current vertex is free and there is
  164.             // an augmenting path from current vertex
  165.             if (pairU[u] == NILL && dfs(u))
  166.             {
  167.                 max_match++;
  168.             }
  169.         }
  170.     }
  171.     return max_match;
  172. }
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182. int main()
  183. {
  184.     //freopen("in.txt", "r", stdin);
  185.  
  186.     int tEdge;
  187.     cin >> m >> n >> tEdge;
  188.  
  189.     for (int e=1; e<=tEdge; e++)
  190.     {
  191.         int u, v;
  192.         cin >> u >> v;
  193.  
  194.         G[u].pb(v);
  195.         G[v].pb(u);
  196.     }
  197.     cout << "Size of matching is : " << hopcropt_carp() << endl;
  198.  
  199.     cout << "\n\tMatch pairs\nLeft Side ------- Right Side" << endl;
  200.  
  201.     for (int u=1; u<=m; u++)
  202.     {
  203.         // for directed pair
  204.         //cout << "    " << u << "    -------    " << pairU[u] << endl;
  205.        
  206.         // for undirected pair
  207.         cout << "    " << u << "    -------    " << pairV[u] << endl;
  208.     }
  209. }
  210.  
  211. /*******    Input Output     **********************/
  212. 4 4 6
  213. 1 2
  214. 1 3
  215. 2 1
  216. 3 2
  217. 4 2
  218. 4 4
  219.  
  220. Size of matching is : 4
  221. Match pairs
  222. Left Side ------- Right Side
  223.     1    -------    3
  224.     2    -------    1
  225.     3    -------    2
  226.     4    -------    4
  227. /************************************************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement