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); }
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); }
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()); }
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()); }
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(); */ }
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); }