private void FillVoxelPoint(Point3D voxelPoint) { var bot = _scene.GetFirstBot(); var botVector = Vector3D.FromPoint(bot.Current); var voxelVector = Vector3D.FromPoint(voxelPoint); var dsuIndex = GetPointDSUIndex(voxelPoint); if (voxelPoint.Y == 0) { // foreach (var point in FilledAdjacent(voxelPoint)) // { // var p = GetPointDSUIndex(point); // _dsu.Union(p, dsuIndex); // } _dsu.Union(0, dsuIndex); } else { var adjacentFilled = FilledAdjacent(voxelPoint).ToList(); if (adjacentFilled.Count > 0) { foreach (var point in adjacentFilled) { var p = GetPointDSUIndex(point); _dsu.Union(p, dsuIndex); } } else { if (_scene.SceneState.HarmonicsMode == HarmonicsMode.Grounded) { ApplyCommand(new FlipCommand()); } } } _voxelsFilled += 1; ApplyCommand(new FillCommand(voxelVector - botVector)); if (_voxelsFilled == _dsu.SizeOf(0) - 2) { if (_scene.SceneState.HarmonicsMode == HarmonicsMode.Floating) { ApplyCommand(new FlipCommand()); } } else { if (_scene.SceneState.HarmonicsMode == HarmonicsMode.Grounded) { ApplyCommand(new FlipCommand()); } } }
static void Main() { string[] lines = File.ReadAllLines("dsu.in"); int n = int.Parse(lines[0]); DSU dsu = new DSU(); for (int i = 1; i <= n; ++i) dsu.AddSingleItem(i); StreamWriter sw = new StreamWriter("dsu.out"); foreach (string s in lines.Skip(1)) { string[] parts = s.Split(' '); if (parts[0] == "union") { int a = int.Parse(parts[1]) - 1, b = int.Parse(parts[2]) - 1; dsu.Union(a,b); } else if (parts[0] == "get") { int a = int.Parse(parts[1]) - 1; DSU.DsuSet x = dsu.Get(a); sw.WriteLine("{0} {1} {2}", x.Min, x.Max, x.Count); } } sw.Close(); }
public IList <int> NumIslands2(int rows, int cols, int[,] positions) { var dsu = new DSU(rows * cols); var result = new List <int>(); int GetIndx(int r, int c) => r * cols + c; for (var i = 0; i < positions.GetLength(0); i++) { var r = positions[i, 0]; var c = positions[i, 1]; var indx = GetIndx(r, c); dsu.Set(indx); var up = GetIndx(r - 1, c); if (r - 1 >= 0 && dsu.IsSet(up)) { dsu.Union(indx, up); } var down = GetIndx(r + 1, c); if (r + 1 < rows && dsu.IsSet(down)) { dsu.Union(indx, down); } var left = GetIndx(r, c - 1); if (c - 1 >= 0 && dsu.IsSet(left)) { dsu.Union(indx, left); } var right = GetIndx(r, c + 1); if (c + 1 < cols && dsu.IsSet(right)) { dsu.Union(indx, right); } result.Add(dsu.GetCount()); } return(result); }
/// <summary> /// Nov. 19, 2020 /// Union find algorithm /// study code /// https://leetcode.com/problems/sentence-similarity-ii/solution/ /// Time complexity: /// Time Complexity: O(N log P + P), where N is the maximum length of words1 and words2, /// and P is the length of pairs. If we used union-by-rank, this complexity improves to /// O(N * a(P) + P), close to O(N + P), where α is the Inverse-Ackermann function. /// </summary> /// <param name="words1"></param> /// <param name="words2"></param> /// <param name="pairs"></param> /// <returns></returns> public bool AreSentencesSimilarTwo(string[] words1, string[] words2, IList <IList <string> > pairs) { var length1 = words1.Length; var length2 = words2.Length; var pLength = pairs.Count; if (length1 != length2) { return(false); } // index -> indexMap better name? var indexMap = new Dictionary <string, int>(); int count = 0; var dsu = new DSU(2 * pLength); foreach (var pair in pairs) { // go through two words in one pair foreach (var p in pair) { if (!indexMap.ContainsKey(p)) { indexMap.Add(p, count++); } } dsu.Union(indexMap[pair[0]], indexMap[pair[1]]); } for (int i = 0; i < length1; ++i) { var w1 = words1[i]; var w2 = words2[i]; if (w1.CompareTo(w2) == 0) { continue; } if (!indexMap.ContainsKey(w1) || !indexMap.ContainsKey(w2) || dsu.Find(indexMap[w1]) != dsu.Find(indexMap[w2])) { return(false); } } return(true); }
public int[] FindRedundantConnection2(int[][] edges) { DSU = new DSU(edges.Length + 1); foreach (int[] edge in edges) { if (DSU.Union(edge[0], edge[1])) { return(edge); } } return(edges[0]); }
private int[] FindRedundantConnection(int[][] edges) { DSU dsu = new DSU(edges.Length); foreach (int[] edge in edges) { if (!dsu.Union(edge[0], edge[1])) { return(edge); } } throw new ArgumentException("Invalid argument"); }
public int RemoveStones(int[][] stones) { var dsu = new DSU(20000); foreach (var stone in stones) { dsu.Union(stone[0], stone[1] + 10000); } var seen = new HashSet <int>(); foreach (var stone in stones) { seen.Add(dsu.Find(stone[0])); } return(stones.Length - seen.Count); }
private int MinCostToConnectNodes(int N, int[][] connections) { Array.Sort(connections, (a, b) => a[2] - b[2]); DSU dsu = new DSU(N + 1); int cost = 0; foreach (int[] arr in connections) { if (!dsu.Union(arr[0], arr[1])) { cost += arr[2]; } } return(dsu.Count == 2 ? cost : -1); }
public IList <IList <string> > AccountsMerge(IList <IList <string> > accounts) { EmailToId = new Dictionary <string, int>(); EmailToName = new Dictionary <string, string>(); foreach (var account in accounts) { if (account.Count < 2) { continue; } var name = account[0]; for (var i = 1; i < account.Count; i++) { if (!EmailToId.ContainsKey(account[i])) { var id = EmailToId.Count; EmailToId[account[i]] = id; EmailToName[account[i]] = name; } } } var totalAccounts = EmailToId.Count; DSU = new DSU(totalAccounts); foreach (var account in accounts) { // var name = account[0]; for (var i = 1; i < account.Count - 1; i++) { var id1 = EmailToId[account[i]]; var id2 = EmailToId[account[i + 1]]; if (id1 != id2) { DSU.Union(id1, id2); } } } var result = new Dictionary <int, List <string> >(); foreach (var email in EmailToName.Keys) { int index = DSU.Find(EmailToId[email]); if (result.TryGetValue(index, out var list)) { list.Add(email); } else { result[index] = new List <string> { email }; } } foreach (var emails in result.Values) { emails.Sort((x, y) => { var i = 0; while (i < x.Length && i < y.Length) { if (x[i] != y[i]) { return(x[i].CompareTo(y[i])); } i++; } return(x.Length.CompareTo(y.Length)); }); emails.Insert(0, EmailToName[emails[0]]); } return(result.Values.ToList <IList <string> >()); }