public void Smoke_Test_DisJointSet() { var disjointSet = new DisJointSet <int>(); for (int i = 1; i <= 7; i++) { disjointSet.MakeSet(i); } disjointSet.Union(1, 2); Assert.AreEqual(1, disjointSet.FindSet(2)); disjointSet.Union(2, 3); Assert.AreEqual(1, disjointSet.FindSet(3)); disjointSet.Union(4, 5); Assert.AreEqual(4, disjointSet.FindSet(4)); disjointSet.Union(5, 6); Assert.AreEqual(4, disjointSet.FindSet(5)); disjointSet.Union(6, 7); Assert.AreEqual(4, disjointSet.FindSet(6)); Assert.AreEqual(4, disjointSet.FindSet(4)); disjointSet.Union(3, 4); Assert.AreEqual(1, disjointSet.FindSet(4)); }
FindMinimumSpanningTree(WeightedGraph <T, W> graph) { var edges = new List <MSTEdge <T, W> >(); //gather all unique edges DFS(graph.ReferenceVertex, new HashSet <T>(), new Dictionary <T, HashSet <T> >(), edges); //quick sort preparation var sortArray = new MSTEdge <T, W> [edges.Count]; for (int i = 0; i < edges.Count; i++) { sortArray[i] = edges[i]; } //quick sort edges var sortedEdges = MergeSort <MSTEdge <T, W> > .Sort(sortArray); var result = new List <MSTEdge <T, W> >(); var disJointSet = new DisJointSet <T>(); //create set foreach (var vertex in graph.Vertices) { disJointSet.MakeSet(vertex.Key); } //pick each edge one by one //if both source & target belongs to same set //then don't add the edge to result //otherwise add it to result and union sets for (int i = 0; i < edges.Count; i++) { var currentEdge = sortedEdges[i]; var setA = disJointSet.FindSet(currentEdge.Source); var setB = disJointSet.FindSet(currentEdge.Destination); //can't pick edge with both ends already in MST if (setA.Equals(setB)) { continue; } result.Add(currentEdge); //union picked edge vertice sets disJointSet.Union(setA, setB); } return(result); }
public int MinMalwareSpread(int[][] graph, int[] initial) { var ds = new DisJointSet(graph.Length); for (int i = 0; i < graph.Length; i++) { for (int j = i + 1; j < graph.Length; j++) { if (graph[i][j] == 1) { ds.Union(i, j); } } } var Count = new int[graph.Length]; foreach (var node in initial) { Count[ds.Find(node)]++; } int ans = -1, ansSize = -1; foreach (var node in initial) { int root = ds.Find(node); if (Count[root] == 1) { int curSize = ds.Size(root); if (curSize > ansSize || (curSize == ansSize && node < ans)) { ans = node; ansSize = curSize; } } } if (ans == -1) { ans = Int16.MaxValue; foreach (var node in initial) { ans = Math.Min(ans, node); } } return(ans); }