Exemple #1
0
        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]));
                }
            }
        }
    }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
                }
            }
        }
Exemple #6
0
        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);
        }