[关闭]
@lychee123 2017-09-17T19:33:26.000000Z 字数 1775 阅读 1255

Power Oj-1736:飞行员配对方案问题(网络流(最大流———Dinic算法))

图论 AAA不懂


Dinic算法简介
Dinic算法是网络流最大流的优化算法之一,每一步对原图进行分层,然后用DFS求增广路。时间复杂度是O(n^2*m)。

  1. From洋哥的模板先放这里,对dinic还不懂的我)
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. const int maxn = 100;
  5. const int maxm = 4000;
  6. struct EDGE
  7. {
  8. int to, next, flow;
  9. EDGE(int to = 0, int next = 0, int flow = 0): to(to), next(next), flow(flow) {}
  10. } edge[maxm];
  11. int head[maxn], edgecnt, maxNodeNum;
  12. void init()
  13. {
  14. memset(head, -1, sizeof(head));
  15. edgecnt = 0;
  16. maxNodeNum = 0;
  17. }
  18. void AddEdge(int s, int t, int c)
  19. {
  20. edge[edgecnt] = EDGE(t, head[s], c);
  21. head[s] = edgecnt++;
  22. edge[edgecnt] = EDGE(s, head[t], 0);
  23. head[t] = edgecnt++;
  24. maxNodeNum = max(maxNodeNum, max(s, t));
  25. }
  26. int layer[maxn];
  27. int p[maxn];
  28. bool GetLayer(int st, int en)
  29. {
  30. memset(layer, 0, sizeof(int) * (maxNodeNum + 1));
  31. layer[st] = 1;
  32. queue<int>q;
  33. q.push(st);
  34. while(!q.empty())
  35. {
  36. int u = q.front();
  37. q.pop();
  38. for(int i = head[u]; ~i; i = edge[i].next)
  39. {
  40. if(edge[i].flow == 0)
  41. continue;
  42. int v = edge[i].to;
  43. if(layer[v])
  44. continue;
  45. layer[v] = layer[u] + 1;
  46. q.push(v);
  47. }
  48. }
  49. return layer[en];
  50. }
  51. int dfsFlow(int u, int en, int f)
  52. {
  53. int ret = 0;
  54. if(u == en)
  55. return f;
  56. if(layer[u] >= layer[en])
  57. return 0;
  58. for(; ~p[u]; p[u] = edge[p[u]].next)
  59. {
  60. if(edge[p[u]].flow == 0)
  61. continue;
  62. int v = edge[p[u]].to;
  63. if(layer[v] != layer[u] + 1)
  64. continue;
  65. int temp = dfsFlow(v, en, min(f, edge[p[u]].flow));
  66. ret += temp;
  67. f -= temp;
  68. edge[p[u]].flow -= temp;
  69. edge[p[u] ^ 1].flow += temp;
  70. if(f == 0)
  71. break;
  72. }
  73. return ret;
  74. }
  75. int dinic(int st, int en)
  76. {
  77. int ans = 0;
  78. while(GetLayer(st, en))
  79. {
  80. memcpy(p, head, sizeof(int) * (maxNodeNum + 1));
  81. ans += dfsFlow(st, en, INT_MAX);
  82. }
  83. return ans;
  84. }
  85. int main()
  86. {
  87. init();
  88. int n, m;
  89. scanf("%d %d", &n, &m);
  90. for(int i = 1; i <= n; i++)
  91. AddEdge(0, i, 1);
  92. for(int i = n + 1; i <= m; i++)
  93. AddEdge(i, m + 1, 1);
  94. int u, v;
  95. while(scanf("%d %d", &u, &v), u != -1 && v != -1)
  96. {
  97. AddEdge(u, v, 1);
  98. }
  99. int ans = dinic(0, m + 1);
  100. if(ans == 0)
  101. {
  102. printf("No Solution!");
  103. return 0;
  104. }
  105. printf("%d\n", ans);
  106. for(int i = 1; i <= n; i++)
  107. for(int j = head[i]; ~j; j = edge[j].next)
  108. if(edge[j].to > n && edge[j].flow == 0)
  109. {
  110. printf("%d %d\n", i, edge[j].to);
  111. break;
  112. }
  113. return 0;
  114. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注