MaxBipartiteMatching_sqrt.cc 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Hopcroft–Karp algorithm (not sure)
  2. // O(sqrt(n)*E)
  3. // Use : set G (adjacency list), set uN, then m = MaxMatch() and the result is in Mx and My
  4. const int MAXN = 1000; const int INF = 0x3f3f3f3f; vector<int>G [MAXN];
  5. int uN;
  6. int Mx[MAXN],My[MAXN]; int dx[MAXN],dy[MAXN]; int dis;
  7. bool used[MAXN];
  8. bool SearchP() {
  9. queue<int>Q;
  10. dis = INF;
  11. memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy));
  12. for(int i = 0 ; i < uN; i++)
  13. if(Mx[i] == -1) {
  14. Q.push(i);
  15. dx[i] = 0;
  16. }
  17. while(!Q.empty()) {
  18. int u = Q.front();
  19. Q.pop();
  20. if(dx[u] > dis) break;
  21. int sz = G[u].size();
  22. for(int i = 0;i < sz;i++) {
  23. int v = G[u][i];
  24. if(dy[v] == -1) {
  25. dy[v] = dx[u] + 1;
  26. if(My[v] == -1) dis = dy[v];
  27. else {
  28. dx[My[v]] = dy[v] + 1;
  29. Q.push( My[v ]);
  30. }
  31. }
  32. }
  33. }
  34. return dis != INF;
  35. }
  36. bool DFS(int u) {
  37. int sz = G[u].size();
  38. for(int i = 0;i < sz;i++) {
  39. int v = G[u][i];
  40. if(!used[v] && dy[v] == dx[u] + 1) {
  41. used[v] = true;
  42. if(My[v] != -1 && dy[v] == dis) continue;
  43. if(My[v] == -1 || DFS(My[v])) {
  44. My[v] = u; Mx[u] = v; return true;
  45. }
  46. }
  47. }
  48. return false;
  49. }
  50. int MaxMatch() {
  51. int res = 0;
  52. memset(Mx,-1,sizeof(Mx)); memset(My,-1,sizeof(My));
  53. while(SearchP()) {
  54. memset(used,false,sizeof(used));
  55. for(int i = 0;i < uN;i++)
  56. if(Mx[i] == -1 && DFS(i)) res++;
  57. }
  58. return res;
  59. }