Advertisement
igoryanchik

Hopcroft Karp

Jan 14th, 2024 (edited)
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.62 KB | None | 0 0
  1. #include <iostream>
  2. #include <queue>
  3. #include <vector>
  4.  
  5. using namespace std;
  6. const int inf = 1e9;
  7.  
  8. //bfs используем для поиска вершин, которые еще не лежат в пар.соче.
  9. bool bfs(const vector<vector<int>> &graph, vector<int> &available, vector<int> &match, int len)
  10. {
  11.     queue<int> q;
  12.  
  13.     //помечаем 0 все доступные вершины, т.е те, которые не взяты в пар.соч., те вершины, что в пар.соче. помечаем inf
  14.     for (int i = 1; i < len; ++i)
  15.     {
  16.         if (match[i] == 0)
  17.         {
  18.             available[i] = 0;
  19.             q.push(i);
  20.  
  21.         }
  22.         else available[i] = inf;
  23.     }
  24.  
  25.     available[0] = inf;
  26.  
  27.     while (!q.empty())
  28.     {
  29.         int v = q.front();
  30.         q.pop();
  31.  
  32.         if (v == 0) continue;
  33.  
  34.         for (int u : graph[v])
  35.         {
  36.             //если смежная вершина для right == inf, то это говорит о том, что right нигде не задействована,
  37.             //а значит в нее можно попасть только из left
  38.             if (available[match[right]] == inf)
  39.             {
  40.  
  41.                 cout << '\n';
  42.                 for (int it : available)
  43.                     cout << it << " ";
  44.                 cout << '\n';
  45.  
  46.                 available[match[u]] = available[v] + 1;
  47.                 q.push(match[u]);
  48.             }
  49.  
  50.         }
  51.     }
  52.  
  53.     return (available[0] != inf); //если available[0] == inf, то это означает, что нам никак не добраться до фиктивной вершины с помошью
  54.     //увеличивающихся путей, а значит увелчивающихся путей просто нет, то есть найдено максимальное паросочетание
  55. }
  56.  
  57. //ишем увел.путь
  58. bool dfs(const vector<vector<int>> &graph, vector<int> &available, vector<int> &match, int v)
  59. {
  60.     if (v == 0) return 1;
  61.  
  62.     for (int u : graph[v])
  63.     {
  64.         if (available[match[u]] == available[v] + 1 && dfs(graph, available, match, match[u]))
  65.         {
  66.             //увеличивающийся путь переходит в чередующийся
  67.             match[u] = v;
  68.             match[v] = u;
  69.             //std::cout << "\nCurrent Matching; left: " << v << ", right: " << u;
  70.  
  71.             return 1;
  72.         }
  73.     }
  74.  
  75.     available[v] = inf; //помечаем, что нет увел.путь начинающегося с вершины left, больше отсюда не пробуем искать увел.пути
  76.  
  77.     return 0;
  78. }
  79.  
  80. int hopcroftKarp(const vector<vector<int>> &graph)
  81. {
  82.     int n = graph.size();
  83.     int ans = 0;
  84.  
  85.     vector<int> match(n, 0);
  86.     vector<int> available(n, 0);
  87.  
  88.     while (bfs(graph, available, match, n)) //пока есть увел.путь
  89.         for (int i = 1; i < n; ++i)
  90.             if (match[i] == 0 && dfs(graph, available, match, i))
  91.                 ans++;
  92.  
  93.     return ans;
  94. }
  95.  
  96.  
  97. int main()
  98. {
  99.  
  100.     vector<vector<int>> graph(11);
  101.  
  102.     graph[1].push_back(6);
  103.     graph[1].push_back(7);
  104.     graph[1].push_back(9);
  105.  
  106.     graph[2].push_back(7);
  107.     graph[2].push_back(8);
  108.     graph[2].push_back(9);
  109.  
  110.     graph[3].push_back(10);
  111.  
  112.     graph[5].push_back(9);
  113.  
  114.     cout << "\nMax matching: " << hopcroftKarp(graph) << '\n';
  115.  
  116.  
  117.     vector<vector<int>> graph2(9);
  118.  
  119.     graph2[5].push_back(1);
  120.     graph2[5].push_back(2);
  121.     graph2[5].push_back(3);
  122.     graph2[5].push_back(4);
  123.  
  124.     graph2[6].push_back(1);
  125.     graph2[6].push_back(2);
  126.     graph2[6].push_back(3);
  127.     graph2[6].push_back(4);
  128.  
  129.     cout << "\nMax matching: " << hopcroftKarp(graph2) << '\n';
  130.  
  131.  
  132.     vector<vector<int>> graph3(7);
  133.  
  134.     graph3[1].push_back(4);
  135.     graph3[1].push_back(5);
  136.     graph3[1].push_back(6);
  137.  
  138.     graph3[2].push_back(4);
  139.  
  140.     graph3[3].push_back(5);
  141.     graph3[3].push_back(6);
  142.  
  143.     cout << "\nMax matching: " << hopcroftKarp(graph3) << '\n';
  144.  
  145.     return 0;
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement