code_junkie

How can I compute the minimum bipartite vertex cover

Nov 14th, 2011
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.98 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. class VertexCover
  7. {
  8. static void Main(string[] args)
  9. {
  10. var v = new VertexCover();
  11. v.ParseInput();
  12. v.FindVertexCover();
  13. v.PrintResults();
  14. }
  15.  
  16. private void PrintResults()
  17. {
  18. Console.WriteLine(String.Join(" ", VertexCoverResult.Select(x => x.ToString()).ToArray()));
  19. }
  20.  
  21. private void FindVertexCover()
  22. {
  23. FindBipartiteMatching();
  24.  
  25. var TreeSet = new HashSet<int>();
  26. foreach (var v in LeftVertices)
  27. if (Matching[v] < 0)
  28. DepthFirstSearch(TreeSet, v, false);
  29.  
  30. VertexCoverResult = new HashSet<int>(LeftVertices.Except(TreeSet).Union(RightVertices.Intersect(TreeSet)));
  31. }
  32.  
  33. private void DepthFirstSearch(HashSet<int> TreeSet, int v, bool left)
  34. {
  35. if (TreeSet.Contains(v))
  36. return;
  37. TreeSet.Add(v);
  38. if (left) {
  39. foreach (var u in Edges[v])
  40. if (u != Matching[v])
  41. DepthFirstSearch(TreeSet, u, true);
  42. } else if (Matching[v] >= 0)
  43. DepthFirstSearch(TreeSet, Matching[v], false);
  44.  
  45. }
  46.  
  47. private void FindBipartiteMatching()
  48. {
  49. Bicolorate();
  50. Matching = Enumerable.Repeat(-1, VertexCount).ToArray();
  51. var cnt = 0;
  52. foreach (var i in LeftVertices) {
  53. var seen = new bool[VertexCount];
  54. if (BipartiteMatchingInternal(seen, i)) cnt++;
  55. }
  56. }
  57.  
  58. private bool BipartiteMatchingInternal(bool[] seen, int u)
  59. {
  60. foreach (var v in Edges[u]) {
  61. if (seen[v]) continue;
  62. seen[v] = true;
  63. if (Matching[v] < 0 || BipartiteMatchingInternal(seen, Matching[v])) {
  64. Matching[u] = v;
  65. Matching[v] = u;
  66. return true;
  67. }
  68. }
  69. return false;
  70. }
  71.  
  72. private void Bicolorate()
  73. {
  74. LeftVertices = new HashSet<int>();
  75. RightVertices = new HashSet<int>();
  76.  
  77. var colors = new int[VertexCount];
  78. for (int i = 0; i < VertexCount; ++i)
  79. if (colors[i] == 0 && !BicolorateInternal(colors, i, 1))
  80. throw new InvalidOperationException("Graph is NOT bipartite.");
  81. }
  82.  
  83. private bool BicolorateInternal(int[] colors, int i, int color)
  84. {
  85. if (colors[i] == 0) {
  86. if (color == 1) LeftVertices.Add(i);
  87. else RightVertices.Add(i);
  88. colors[i] = color;
  89. } else if (colors[i] != color)
  90. return false;
  91. else
  92. return true;
  93. foreach (var j in Edges[i])
  94. if (!BicolorateInternal(colors, j, 3 - color))
  95. return false;
  96. return true;
  97. }
  98.  
  99. private int VertexCount;
  100. private HashSet<int>[] Edges;
  101. private HashSet<int> LeftVertices;
  102. private HashSet<int> RightVertices;
  103. private HashSet<int> VertexCoverResult;
  104. private int[] Matching;
  105.  
  106. private void ReadIntegerPair(out int x, out int y)
  107. {
  108. var input = Console.ReadLine();
  109. var splitted = input.Split(new char[] { ' ' }, 2);
  110. x = int.Parse(splitted[0]);
  111. y = int.Parse(splitted[1]);
  112. }
  113.  
  114. private void ParseInput()
  115. {
  116. int EdgeCount;
  117. ReadIntegerPair(out VertexCount, out EdgeCount);
  118. Edges = new HashSet<int>[VertexCount];
  119. for (int i = 0; i < Edges.Length; ++i)
  120. Edges[i] = new HashSet<int>();
  121.  
  122. for (int i = 0; i < EdgeCount; i++) {
  123. int x, y;
  124. ReadIntegerPair(out x, out y);
  125. Edges[x].Add(y);
  126. Edges[y].Add(x);
  127. }
  128. }
  129. }
  130.  
  131. private void DepthFirstSearch(HashSet TreeSet, int v, bool left)
  132. {
  133. if (TreeSet.Contains(v))
  134. return;
  135. TreeSet.Add(v);
  136. if (left) {
  137. foreach (var u in Edges[v])
  138. if (u != Matching[v])
  139. DepthFirstSearch(TreeSet, u, true);
  140. } else if (Matching[v] >= 0)
  141. DepthFirstSearch(TreeSet, Matching[v], false);
  142.  
  143. }
Add Comment
Please, Sign In to add comment