static void Main(string[] args) { int n = Int32.Parse(Console.ReadLine()); UnionFind uf = new UnionFind(); List <string> names = new List <string>(); for (int i = 0; i < n; i++) { string[] info = Console.ReadLine().Split(); string name = info[0]; names.Add(name); int count = Int32.Parse(info[1]); uf.Add(name, name); for (int j = 2; j < info.Length; j++) { uf.Add(info[j], name); } } Dictionary <string, List <string> > dict = new Dictionary <string, List <string> >(); foreach (string name in names) { string parent = uf.Find(name); if (dict.ContainsKey(parent)) { dict[parent].Add(name); } else { dict[parent] = new List <string>() { name } }; } Dictionary <string, List <string> > dict2 = new Dictionary <string, List <string> >(); foreach (string parent in dict.Keys) { dict2[dict[parent][0]] = dict[parent]; } foreach (string name in names) { if (dict2.ContainsKey(name)) { System.Console.WriteLine(string.Join(" ", dict2[name])); } } } }
/// <summary> /// Builds the minimum-spanning tree using Kruskal's algorithm in O(|E|*log|E|) /// where |E| is the number of Edges /// and |V| the number of vertices (nodes) in the Graph /// </summary> /// <returns></returns> private Tree BuildMinimumSpanningTreeKruskal() { int N = m_nodes.Count; var unionFind = new UnionFind(m_nodes); //O(|V|) Func <Edge, Edge, int> cmp = (a, b) => a.CompareTo(b); var heap = new List <Edge>(EdgeCount); foreach (var e in Edges) { heap.HeapEnqueue(cmp, e); } var tree = new Tree(this); long i = 0; //O(|E|*log|E|) while (tree.EdgeCount < N - 1) { var edge = heap.HeapDequeue(cmp); i++; //O(1) amortized if (unionFind.Add(edge.Index0, edge.Index1)) { //O(1) tree.AddEdge(edge); } } //O(|V| + |E|*log|E|) return(tree); }
public static Decimal Run(IEnumerable <string> lines) { var swAll = new Stopwatch(); var sw = new Stopwatch(); swAll.Start(); sw.Start(); var counts = lines.First().Split(' ', '\t'); var vertexcount = int.Parse(counts[0]); var edgesCount = int.Parse(counts[1]); var edges = lines.Skip(1).Where(c => !String.IsNullOrWhiteSpace(c)).Select(c => { var values = c.Split(' ', '\t'); //Debug.Assert(values.Length == 3); return(new { From = LoadHelper.Parse(values[0]), To = LoadHelper.Parse(values[1]), Cost = LoadHelper.DecimalParse(values[2]) }); }).ToArray(); sw.Stop(); Console.WriteLine("Загрузили строки в массив ребер за {0}", sw.Elapsed); sw.Restart(); //var vertices = edges.Select(c => c.From).Concat(edges.Select(c => c.To)).Distinct(); var unionFind = new UnionFind(vertexcount); for (int i = 0; i < vertexcount; i++) { unionFind.Add(i); } sw.Stop(); Console.WriteLine("Загрузили вершины в юнионфайнд за {0}", sw.Elapsed); //sw.Restart(); //Array.Sort(edges, (x,y)=>x.Cost.CompareTo(y.Cost)); //sw.Stop(); //Console.WriteLine("сортировка массива ребер за {0}", sw.Elapsed); sw.Restart(); var result = edges.OrderBy(c => c.Cost).Where(edge => unionFind.Union(edge.From, edge.To)).Sum(edge => edge.Cost); sw.Stop(); Console.WriteLine("вычисление mst за {0}", sw.Elapsed); swAll.Stop(); Console.WriteLine("итого: {0}", result); Console.WriteLine("за время: {0}", swAll.Elapsed); return(result); }
public static int Run(IEnumerable <string> lines, int minSpacingDistance) { var sw = new Stopwatch(); var nodes = lines.Where(c => !String.IsNullOrWhiteSpace(c)) .Select(c => LoadHelper.ParseBits(c)).Distinct().Select((c, i) => new Node() { Label = i, Value = c }).ToDictionary(c => c.Value, c => c); //, }); sw.Start(); var links = nodes.Values.SelectMany(node => _distances[1], (node, distance) => { Node node1; return(nodes.TryGetValue(node.Value ^ distance, out node1) ? new Link { From = node.Label, Distance = 1, To = node1.Label } : null); }) .Concat(nodes.Values.SelectMany(node => _distances[2], (node, distance) => { Node node1; return(nodes.TryGetValue(node.Value ^ distance, out node1) ? new Link { From = node.Label, Distance = 2, To = node1.Label } : null); })) .Where(c => c != null) .OrderBy(c => c.Distance); var unionFind = new UnionFind(nodes.Count); foreach (var node in nodes.Values) { unionFind.Add(node.Label); } foreach (var link in links) { unionFind.Union(link.From, link.To); } sw.Stop(); Console.WriteLine(sw.Elapsed); return(unionFind.RootCount); }
public static IEnumerable <Tuple <TVertex, TVertex> > GetMST(UndirectedWeightedGraph <TVertex> graph) { if (graph == null) { throw new ArgumentNullException("graph", "Specify a non-null argument."); } if (graph.VertexCount == 0) { yield break; } if (ConnectedComponents <TVertex> .GetConnectedComponentsCount(graph) > 1) { throw new InvalidOperationException("Graph is not connected."); } PriorityQueue <Edge> queue = new PriorityQueue <Edge>(); UnionFind <TVertex> connectedComponents = new UnionFind <TVertex>(); foreach (TVertex vertex in graph.GetVertices()) { connectedComponents.Add(vertex); foreach (TVertex neighbour in graph.GetNeighbours(vertex)) { queue.Enqueue(new Edge(vertex, neighbour, graph.GetEdgeWeight(vertex, neighbour))); } } List <Tuple <TVertex, TVertex> > mst = new List <Tuple <TVertex, TVertex> >(); while (!queue.IsEmpty()) { Edge minCostEdge = queue.Dequeue(); if (!connectedComponents.AreConnected(minCostEdge.Vertex1, minCostEdge.Vertex2)) { yield return(Tuple.Create(minCostEdge.Vertex1, minCostEdge.Vertex2)); connectedComponents.Union(minCostEdge.Vertex1, minCostEdge.Vertex2); } } }
public void TestUnionFind() { var uf = new UnionFind <int>(); for (int i = 0; i <= 10; ++i) { Assert.AreEqual(i, uf.Find(i)); Assert.AreEqual(i + 1, uf.Count); Assert.AreEqual(i + 1, uf.DistinctFamilyCount); } for (int i = 0; i <= 10; ++i) { Assert.AreEqual(false, uf.Union(i, i)); } //we join all even values for (int i = 2; i <= 10; i += 2) { Assert.AreEqual(true, uf.Union(0, i)); Assert.AreEqual(11, uf.Count); Assert.AreEqual(uf.Find(0), uf.Find(i)); } for (int i = 0; i <= 10; i += 2) { Assert.AreEqual(false, uf.Union(0, i)); } Assert.AreEqual(1 + 5, uf.DistinctFamilyCount); //we join all odd values for (int i = 3; i <= 9; i += 2) { Assert.AreEqual(true, uf.Union(1, i)); Assert.AreEqual(11, uf.Count); Assert.AreEqual(uf.Find(1), uf.Find(i)); } for (int i = 1; i <= 9; i += 2) { Assert.AreEqual(false, uf.Union(1, i)); } Assert.AreEqual(2, uf.DistinctFamilyCount); //we join all values Assert.AreEqual(true, uf.Union(9, 10)); Assert.AreEqual(11, uf.Count); Assert.AreEqual(1, uf.DistinctFamilyCount); for (int i = 0; i <= 10; ++i) { for (int j = 0; j <= 10; ++j) { Assert.AreEqual(false, uf.Union(i, j)); Assert.AreEqual(uf.Find(i), uf.Find(j)); } } uf = new UnionFind <int>(); Assert.IsTrue(uf.Add(1)); Assert.IsTrue(uf.Add(2)); Assert.IsTrue(uf.Add(3)); Assert.IsFalse(uf.Add(2)); Assert.AreEqual(3, uf.Count); Assert.AreEqual(3, uf.DistinctFamilyCount); uf.Union(1, 2); Assert.AreEqual(3, uf.Count); Assert.AreEqual(2, uf.DistinctFamilyCount); }