dfs模板 二部图的最大匹配

  1. /****************************************************
  2. 二分图匹配(匈牙利算法的DFS实现)
  3. INIT:g[][]两边定点划分的情况
  4. CALL:res=hungary();输出最大匹配数
  5. 优点:适于稠密图,DFS找增广路快,实现简洁易于理解
  6. 时间复杂度:O(VE);
  7. 适用范围:
  8. 二分图的 最小顶点覆盖 ==== 最大匹配
  9. DAG图的 最小路径覆盖数 == 节点数 – 最大匹配数
  10. 二分图的 最大独立集数 = 节点数 – 最大匹配数
  11. ****************************************************/
  12. #include <string>
  13. #include <stdio.h>
  14. using namespace std;
  15. #define MAXN 1000
  16. int path[MAXN][MAXN];
  17. bool sign[MAXN]; //v是否已经匹配的标志
  18. int road[MAXN]; //匹配存在road中,从v->u的
  19. int u_num, v_num; //两个集合各自的元素总数
  20. bool dfs(int u)
  21. {
  22. for(int v=0; v<=v_num; v++) //这里加个等于号和题目有关
  23. {
  24. if(path[u][v] && !sign[v]) //path[u][v] 存在关联与否,与没有匹配的v结合
  25. {
  26. sign[v] = true; //结合后的v设定为匹配
  27. if(road[v] == -1 || dfs(road[v]) )
  28. {
  29. road[v] = u; //保存u->v的匹配路径
  30. return true;
  31. }
  32. }
  33. }
  34. return false;
  35. }
  36. int hungray()
  37. {
  38. int match = 0; //匹配数
  39. memset(road, -1, sizeof(road) ); //匹配路径初始化
  40. for(int u=0; u<=u_num; u++)
  41. {
  42. memset(sign, 0, sizeof(sign) ); //每查找一次u, v集合相应清空
  43. if(dfs(u) ) match++;
  44. }
  45. return match;
  46. }
  47. void input(int n)
  48. {
  49. memset(path, 0,sizeof(path) );
  50. for(int i=0; i<n; i++)
  51. {
  52. int u, v;
  53. scanf("%d%d", &u, &v);
  54. path[u][v] = 1;
  55. }
  56. }
  57. int main()
  58. {
  59. int n;
  60. while(scanf("%d")!=EOF)
  61. {
  62. scanf("%d%d", &u_num, &v_num);
  63. input(n);
  64. printf("%d n", hungray() );
  65. }
  66. return 0;
  67. }





附件列表

    原文地址:https://www.cnblogs.com/sober-reflection/p/adc5d1c2d2d891eaadf82cb63cfe5b13.html