Beispiel #1
0
    public void Solve()
    {
        Init();
        Queue <List <int> > cand = new Queue <List <int> >(), nextCand;
        Queue <int>         range = new Queue <int>(), nextRange;

        cand.Enqueue(Enu.Range(0, NQ).ToList());
        range.Enqueue(0); range.Enqueue(M);
        var ans = new int[NQ];

        for (; cand.Count > 0; cand = nextCand, range = nextRange)
        {
            nextCand  = new Queue <List <int> >();
            nextRange = new Queue <int>();
            var uf = new UnionFind(N);
            while (cand.Count > 0)
            {
                var who = cand.Dequeue();
                int L = range.Dequeue(), R = range.Dequeue(), mid = L + R >> 1;
                for (int i = L; i < mid; i++)
                {
                    uf.Unite(E[i][0], E[i][1]);
                }
                var next = new[] { new List <int>(), new List <int>() };
                foreach (int i in who)
                {
                    int num = uf.Count(Q[i][0]) + (uf.Same(Q[i][0], Q[i][1]) ? 0 : uf.Count(Q[i][1]));
                    if (num >= Q[i][2])
                    {
                        ans[i] = mid; next[0].Add(i);
                    }
                    else
                    {
                        next[1].Add(i);
                    }
                }
                for (int i = mid; i < R; i++)
                {
                    uf.Unite(E[i][0], E[i][1]);
                }
                if (L == R - 1)
                {
                    who.ForEach(i => ans[i] = R); continue;
                }
                nextCand.Enqueue(next[0]); nextCand.Enqueue(next[1]);
                nextRange.Enqueue(L); nextRange.Enqueue(mid);
                nextRange.Enqueue(mid); nextRange.Enqueue(R);
            }
        }

        Console.WriteLine(string.Join("\n", ans));
    }
        public int RegionsBySlashes(string[] grid)
        {
            var N  = grid.Length;
            var uf = new UnionFind(4 * N * N);

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    if (i > 0)
                    {
                        uf.Union(ComputeIndex(i, j, 0, N), ComputeIndex(i - 1, j, 2, N));
                    }
                    if (j > 0)
                    {
                        uf.Union(ComputeIndex(i, j, 3, N), ComputeIndex(i, j - 1, 1, N));
                    }
                    if (grid[i][j] != '\\')
                    {
                        uf.Union(ComputeIndex(i, j, 0, N), ComputeIndex(i, j, 3, N));
                        uf.Union(ComputeIndex(i, j, 1, N), ComputeIndex(i, j, 2, N));
                    }
                    if (grid[i][j] != '/')
                    {
                        uf.Union(ComputeIndex(i, j, 0, N), ComputeIndex(i, j, 1, N));
                        uf.Union(ComputeIndex(i, j, 2, N), ComputeIndex(i, j, 3, N));
                    }
                }
            }

            return(uf.Count());
        }
            //实现1.5.2.1
            static void Main()
            {
                int       totalIDs          = 50000000;
                int       unions            = 200000;
                int       offset            = unions / 2;
                UnionFind uf                = new UnionFind(totalIDs);
                UnionFind uf_quick          = new UnionFind(totalIDs); //使用快速连接
                UnionFind uf_quick_compress = new UnionFind(totalIDs); //使用路径压缩和快速连接

                //uf.Union(0, 1);
                //uf.Union(0, 5);
                //uf.Union(2, 6);
                //uf.Union(6, 7);
                //uf.Union(3, 8);
                //uf.Union(3,9);
                //uf.Union(4, 3);
                //uf.Union_UnionSubTree(0, 1);
                //uf.Union_UnionSubTree(0, 5);
                //uf.Union_UnionSubTree(2, 6);
                //uf.Union_UnionSubTree(6, 7);
                //uf.Union_UnionSubTree(3, 8);
                //uf.Union_UnionSubTree(3, 9);
                //uf.Union_UnionSubTree(4, 3);
                int[]     links      = Common.GenerateRadomData(unions, 0, totalIDs);
                Stopwatch Stopwatch1 = new Stopwatch();

                Stopwatch1.Start();
                for (int i = 0; i < offset; ++i)
                {
                    ;//uf.Union(links[i], links[i + offset]);
                }
                Stopwatch1.Stop();
                Console.WriteLine("没有优化Use :" + Stopwatch1.ElapsedMilliseconds.ToString());
                Console.WriteLine(uf.Count());
                //quick-union
                Stopwatch Stopwatch2 = new Stopwatch();

                Stopwatch2.Start();
                for (int i = 0; i < offset; ++i)
                {
                    uf_quick.Union_QuickUnion(links[i], links[i + offset]);
                }
                Stopwatch2.Stop();
                Console.WriteLine("快速union Use :" + Stopwatch2.ElapsedMilliseconds.ToString());
                Console.WriteLine(uf_quick.Count());
                //quick-union和压缩路径
                Stopwatch Stopwatch3 = new Stopwatch();

                Stopwatch3.Start();
                for (int i = 0; i < offset; ++i)
                {
                    uf_quick_compress.Union_UnionSubTree(links[i], links[i + offset]);
                }
                Stopwatch3.Stop();
                Console.WriteLine("快速union+路径压缩 use :" + Stopwatch3.ElapsedMilliseconds.ToString());
                Console.WriteLine(uf_quick_compress.Count());
                Console.ReadKey();
            }
    public bool ValidTree(int n, int[,] edges)
    {
        UnionFind uf = new UnionFind(n);

        for (int i = 0; i < edges.GetLength(0); i++)
        {
            // 已经在一个集合中,形成了环
            if (!uf.Union(edges[i, 0], edges[i, 1]))
            {
                return(false);
            }
        }
        // 只有一个集合才是树
        return(uf.Count() == 1);
    }
Beispiel #5
0
    public int FindCircleNum(int[][] M)
    {
        int       n  = M.length;
        UnionFind uf = new UnionFind(n);

        for (int i = 0; i < n - 1; i++)
        {
            for (int j = i + 1; j < n; j++)
            {
                if (M[i][j] == 1)
                {
                    uf.Union(i, j);
                }
            }
        }
        return(uf.Count());
    }
        public int ClosedIsland(int[][] grid)
        {
            var N = grid.Length;
            var M = grid[0].Length;

            var uf = new UnionFind(grid);

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < M; j++)
                {
                    if (grid[i][j] == 0)
                    {
                        if (i == 0 || j == 0 || i == N - 1 || j == M - 1)
                        {
                            uf.Union(i * M + j, N * M);
                        }

                        if (i - 1 >= 0 && grid[i - 1][j] == 0)
                        {
                            uf.Union(i * M + j, (i - 1) * M + j);
                        }
                        if (i + 1 < N && grid[i + 1][j] == 0)
                        {
                            uf.Union(i * M + j, (i + 1) * M + j);
                        }
                        if (j - 1 >= 0 && grid[i][j - 1] == 0)
                        {
                            uf.Union(i * M + j, i * M + j - 1);
                        }
                        if (j + 1 < M && grid[i][j + 1] == 0)
                        {
                            uf.Union(i * M + j, i * M + j + 1);
                        }
                    }
                }
            }
            return(uf.Count() - 1);
        }
Beispiel #7
0
    public int FindCircleNum(int[,] M)
    {
        if (M == null || M.GetLength(0) == 0 || M.GetLength(1) == 0)
        {
            return(0);
        }

        int       n  = M.GetLength(0);
        UnionFind uf = new UnionFind(n);

        for (int i = 0; i < n; i++)
        {
            for (int j = i + 1; j < n; j++)
            {
                if (M[i, j] == 1)
                {
                    uf.Union(i, j);
                }
            }
        }
        return(uf.Count());
    }
Beispiel #8
0
        public int NumIslands(char[][] grid)
        {
            if (grid == null || grid.Length == 0 || grid[0].Length == 0)
            {
                return(0);
            }

            var uf = new UnionFind(grid);
            int m  = grid.Length;
            int n  = grid[0].Length;

            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (grid[i][j] == '1')
                    {
                        if (i - 1 >= 0 && grid[i - 1][j] == '1')
                        {
                            uf.Union(i * n + j, (i - 1) * n + j);
                        }
                        if (i + 1 < m && grid[i + 1][j] == '1')
                        {
                            uf.Union(i * n + j, (i + 1) * n + j);
                        }
                        if (j - 1 >= 0 && grid[i][j - 1] == '1')
                        {
                            uf.Union(i * n + j, i * n + j - 1);
                        }
                        if (j + 1 < n && grid[i][j + 1] == '1')
                        {
                            uf.Union(i * n + j, i * n + j + 1);
                        }
                    }
                }
            }
            return(uf.Count());
        }
Beispiel #9
0
    static void Main()
    {
        var nm = ReadInts();
        int n = nm[0], m = nm[1];

        var edges = new List <Edge>();

        for (int i = 0; i < m; i++)
        {
            var aby = ReadInts();
            edges.Add(new Edge {
                a = aby[0] - 1, b = aby[1] - 1, y = aby[2]
            });
        }

        int q  = ReadInt();
        var qs = new List <Query>();

        for (int i = 0; i < q; i++)
        {
            var vw = ReadInts();
            qs.Add(new Query {
                v = vw[0] - 1, w = vw[1], index = i
            });
        }

        var uf = new UnionFind(n);

        edges.Sort((a, b) => - a.y.CompareTo(b.y));
        qs.Sort((a, b) => - a.w.CompareTo(b.w));

        int p   = 0;
        var ans = new int[qs.Count];

        for (int i = 0; i < qs.Count; i++)
        {
            int v = qs[i].v; // ??
            int w = qs[i].w; // w ???????????????
            while (p < edges.Count && edges[p].y > w)
            {
                uf.Unite(edges[p].a, edges[p].b);
                p++;
            }

            ans[qs[i].index] = uf.Count(v);
        }

        var sb = new StringBuilder();

        foreach (var a in ans)
        {
            sb.AppendLine(a.ToString());
        }
        Console.Write(sb.ToString());

        /*
         * Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
         * for (int i = 0; i < ans.Length; i++) {
         *  Console.WriteLine(ans[i]);
         * }
         * Console.Out.Flush();
         */
    }
Beispiel #10
0
    public int NumIslands(char[][] grid)
    {
        //verification
        if (grid == null || grid.Length == 0)
        {
            return(0);
        }

        rows = grid.Length;
        cols = grid[0].Length;
        int count = 0;

        //M1:DFS. O(mn), O(mn)
        // for(int i=0; i<rows; i++){
        //     for(int j=0; j<cols; j++){
        //         if(grid[i][j]=='1'){
        //             count++;
        //             DFS(grid, i,j);
        //         }
        //     }
        // }

        //BFS. O(mn), O(mn)
        // Queue<int[]> queue=new Queue<int[]>();
        // for(int i=0; i<rows; i++){
        //     for(int j=0; j<cols; j++){
        //         if(grid[i][j]=='1'){
        //             count++;
        //             queue.Enqueue(new int[]{i,j});
        //             while(queue.Any()){
        //                 var p=queue.Dequeue();
        //                 for(int k=0; k<4; k++){
        //                     var newx=p[0]+directions[k,0];
        //                     var newy=p[1]+directions[k,1];
        //                     if(IsLand(grid, newx, newy)){
        //                         grid[newx][newy]='0';
        //                         queue.Enqueue(new int[]{newx, newy});
        //                     }
        //                 }
        //             }
        //         }
        //     }
        // }
        // return count;

        //M3: Disjoint set
        int[,] dir = { { 1, 0 }, { 0, 1 } };
        int       node = rows * cols;
        UnionFind uf   = new UnionFind(node + 1);

        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                if (grid[i][j] == '0')
                {
                    uf.Union(GetIndex(i, j), node);
                }
                else if (grid[i][j] == '1')
                {
                    for (int d = 0; d < 2; d++)
                    {
                        var x = i + dir[d, 0];
                        var y = j + dir[d, 1];
                        if (x < rows && y < cols && grid[x][y] == '1')
                        {
                            uf.Union(GetIndex(i, j), GetIndex(x, y));
                        }
                    }
                }
            }
        }
        return(uf.Count() - 1);
    }