예제 #1
0
        public static void DisjointSetTest()
        {
            DisjointSet ds = new DisjointSet();

            ds.MakeSet(1);
            ds.MakeSet(2);
            ds.MakeSet(3);
            ds.MakeSet(4);
            ds.MakeSet(5);
            ds.MakeSet(6);
            ds.MakeSet(7);

            ds.Union(1, 2);
            ds.Union(2, 3);
            ds.Union(4, 5);
            ds.Union(6, 7);
            ds.Union(5, 6);
            ds.Union(3, 7);

            Console.WriteLine("DisjoinSet Demo :");

            Console.WriteLine(ds.FindSet(1));
            Console.WriteLine(ds.FindSet(2));
            Console.WriteLine(ds.FindSet(3));
            Console.WriteLine(ds.FindSet(4));
            Console.WriteLine(ds.FindSet(5));
            Console.WriteLine(ds.FindSet(6));
            Console.WriteLine(ds.FindSet(7));
        }
        public List <Edge> GetKruskalsMST(Graph graph)
        {
            graph.Edges.Sort(new EdgeComparator());

            DisjointSet disjointSet = new DisjointSet();

            // Create as many disjoint sets as the total vertices
            foreach (KeyValuePair <long, Vertex> vertexPair in graph.Verticies)
            {
                disjointSet.MakeSet(vertexPair.Value.Id);
            }

            List <Edge> resultEdges = new List <Edge>();

            foreach (Edge edge in graph.Edges)
            {
                // Get the sets of two vertices of the edge
                long root1 = disjointSet.FindSet(edge.Vertex1.Id);
                long root2 = disjointSet.FindSet(edge.Vertex2.Id);

                // Check if the vertices are in same set or different set
                // If verties are in same set then ignore the edge
                if (root1 == root2)
                {
                    continue;
                }
                else
                {
                    // If vertices are in different set then add the edge to result and union these two sets into one
                    resultEdges.Add(edge);
                    disjointSet.Union(edge.Vertex1.Id, edge.Vertex2.Id);
                }
            }
            return(resultEdges);
        }
        // =======================================================

        /* A 2d grid map of m rows and n columns is initially filled with water.
         * We may perform an addLand operation which turns the water at position (row, col) into a land.
         * Given a list of positions to operate, count the number of islands after each addLand operation.
         * An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically.
         * You may assume all four edges of the grid are all surrounded by water.
         * https://leetcode.com/problems/number-of-islands-ii/
         */

        public List <int> NumberOfIslands2(int rowSize, int colSize, int[,] positions)
        {
            List <int> result = new List <int>();

            if (positions == null || positions.GetLength(0) == 0 || positions.GetLength(1) == 0)
            {
                return(result);
            }

            int           count       = 0;
            DisjointSet   dsSet       = new DisjointSet();
            HashSet <int> landHashSet = new HashSet <int>();

            for (int lpRIndx = 0; lpRIndx < positions.GetLength(0); lpRIndx++)
            {
                int index = positions[lpRIndx, 0] * colSize + positions[lpRIndx, 1];

                landHashSet.Add(index);
                dsSet.MakeSet(index);

                count++;

                // Find the four neighbors;
                int n1 = (positions[lpRIndx, 0] - 1) * colSize + positions[lpRIndx, 1];
                int n2 = (positions[lpRIndx, 0] + 1) * colSize + positions[lpRIndx, 1];
                int n3 = (positions[lpRIndx, 0]) * colSize + positions[lpRIndx, 1] + 1;
                int n4 = (positions[lpRIndx, 0]) * colSize + positions[lpRIndx, 1] - 1;

                if (positions[lpRIndx, 0] - 1 >= 0 && landHashSet.Contains(n1) && dsSet.Union(index, n1))
                {
                    count--;
                }

                if (positions[lpRIndx, 0] + 1 < rowSize && landHashSet.Contains(n2) && dsSet.Union(index, n2))
                {
                    count--;
                }

                if (positions[lpRIndx, 1] + 1 < colSize && landHashSet.Contains(n3) && dsSet.Union(index, n3))
                {
                    count--;
                }

                if (positions[lpRIndx, 1] - 1 >= 0 && landHashSet.Contains(n4) && dsSet.Union(index, n4))
                {
                    count--;
                }

                result.Add(count);
            }
            return(result);
        }
예제 #4
0
        //=======================================================================================================================

        public bool HasCycleUsingDisjointSets(Graph graph)
        {
            DisjointSet disjointSet = new DisjointSet();

            foreach (KeyValuePair <long, Vertex> vertexPair in graph.Verticies)
            {
                disjointSet.MakeSet(vertexPair.Key);
            }

            foreach (Edge edge in graph.Edges)
            {
                long parent1 = disjointSet.FindSet(edge.Vertex1.Id);
                long parent2 = disjointSet.FindSet(edge.Vertex2.Id);

                if (parent1 == parent2)
                {
                    return(true);
                }

                disjointSet.Union(edge.Vertex1.Id, edge.Vertex2.Id);
            }

            return(false);
        }