MaxBipartiteMatching_sqrt.cc 1.3 KB

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