匈牙利算法

来源:互联网 发布:windows 私有云 编辑:程序博客网 时间:2024/05/07 00:39

匈牙利算法

刚刚复习了匈牙利算法。匈牙利算法代码非常短,但是有很多需要注意的地方。

  1. int find(int u)
  2. {
  3. int j = edge.head[u];
  4. while(j)
  5. {
  6. int v = edge.e[j];
  7. if (!vis[v])
  8. {
  9. vis[v] = 1;
  10. if (result[v] == 0 || find(result[v])){
  11. result[v] = u;
  12. result[u] = v;
  13. return 1;
  14. }
  15. }
  16. j = edge.next[j];
  17. }
  18. return 0;
  19. }
  1. 匈牙利算法中find返回True,代表找到一条增广路,匹配数+1,并且原来已经匹配的节点依然处于匹配的状态(可能边不同),两个未匹配的节点变为匹配状态,其中包括第一次调用find时作为参数传入的节点。
  2. 匈牙利算法可以在不知道二部图的情况下使用,只要维护好所有节点的result,即所有节点的匹配状态。因为二部图中匹配时所有的节点都等价,所以不管从二部图的哪一边寻找增广路都是可以的。
  3. 递归搜索时一旦出现了return 1,那么就会沿着调用的路径一直return 1直到退出递归。因此vis[v]=1不需要还原。一个节点最多只会被搜索一次,当它的result改变时一定是第一次搜索到这个节点。

hiho一下 第三十四周

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <memory.h>
  4. using namespace std;
  5. const int N = 2*1005;
  6. const int M = 2*5005;
  7. class my_edge
  8. {
  9. public:
  10. int tot;
  11. int head[N],next[M],e[M];
  12. my_edge();
  13. void addedge(int,int);
  14. };
  15. int n,m;
  16. int result[N],vis[N];
  17. my_edge edge;
  18. void init();
  19. int find(int);
  20. void solve();
  21. int main()
  22. {
  23. init();
  24. solve();
  25. return 0;
  26. }
  27. my_edge::my_edge(){
  28. tot = 0;
  29. memset(head,0,sizeof(head));
  30. }
  31. void my_edge::addedge(int u,int v)
  32. {
  33. tot++;
  34. next[tot] = head[u];head[u] = tot; e[tot] = v;
  35. tot++;
  36. next[tot] = head[v];head[v] = tot; e[tot] = u;
  37. }
  38. void init()
  39. {
  40. scanf("%d %d",&n,&m);
  41. while (m--)
  42. {
  43. int p,q;
  44. scanf("%d %d",&p,&q);
  45. edge.addedge(p,q);
  46. }
  47. }
  48. void solve()
  49. {
  50. int ans = 0;
  51. for (int i = 1; i <= n; i++)
  52. {
  53. memset(vis,0,sizeof(vis));
  54. if (result[i] == 0 && find(i))
  55. {
  56. ans ++;
  57. }
  58. }
  59. cout << ans << endl;
  60. }
  61. int find(int u)
  62. {
  63. int j = edge.head[u];
  64. while(j)
  65. {
  66. int v = edge.e[j];
  67. if (!vis[v])
  68. {
  69. vis[v] = 1;
  70. if (result[v] == 0 || find(result[v])){
  71. result[v] = u;
  72. result[u] = v;
  73. return 1;
  74. }
  75. }
  76. j = edge.next[j];
  77. }
  78. return 0;
  79. }
0 0
原创粉丝点击