Exemplo n.º 1
0
        /// <summary>
        /// assume that maximum number of cities is 50
        /// Map new road as integer quickly.
        /// using SortedDictionary
        /// https://github.com/jianminchen/Leetcode_Julia/blob/master/source%20code/23%20Merge%20K%20sorted%20lists%20-%20using%20minimum%20heap.cs
        /// </summary>
        /// <param name="noCities"></param>
        /// <param name="existingRoads"></param>
        /// <param name="newRoads"></param>
        /// <param name="roadWithCost"></param>
        /// <returns></returns>
        public static int getMinimumCost(
            int noCities,
            List <int[]> existingRoads,
            int newRoads,
            List <int[]> roadWithCost)
        {
            var quickUnion = new QuickUnion(noCities);

            foreach (var item in existingRoads)
            {
                // adjust the value of id from 0 to N - 1
                quickUnion.Union(item[0] - 1, item[1] - 1);
            }

            int count = quickUnion.GetCount();

            var newRoadMap = new SortedDictionary <int, Queue <int[]> >();

            foreach (int[] item in roadWithCost)
            {
                var id1      = item[0] - 1;
                var id2      = item[1] - 1;
                var roadCost = item[2];

                if (!newRoadMap.ContainsKey(roadCost))
                {
                    newRoadMap.Add(roadCost, new Queue <int[]>());
                }

                newRoadMap[roadCost].Enqueue(new int[] { id1, id2 });
            }

            var totalCost = 0;

            while (newRoadMap.Count > 0)
            {
                int minCost = newRoadMap.First().Key;
                var ids     = newRoadMap[minCost].Dequeue();

                if (newRoadMap[minCost].Count == 0)
                {
                    newRoadMap.Remove(minCost);
                }

                var id1 = ids[0];
                var id2 = ids[1];

                var connected = quickUnion.Connected(id1, id2);
                if (connected)
                {
                    continue;
                }

                totalCost += minCost;
                quickUnion.Union(id1, id2); // Union, not Connected

                if (quickUnion.GetCount() == 1)
                {
                    break;
                }
            }

            if (quickUnion.GetCount() > 1)
            {
                return(-1);
            }

            return(totalCost);
        }
        /// <summary>
        /// assume that maximum number of cities is 50
        /// Map new road as integer quickly.
        /// </summary>
        /// <param name="noCities"></param>
        /// <param name="existingRoads"></param>
        /// <param name="newRoads"></param>
        /// <param name="roadWithCost"></param>
        /// <returns></returns>
        public static int getMinimumCost(
            int noCities,
            List <int[]> existingRoads,
            int newRoads,
            List <int[]> roadWithCost)
        {
            var quickUnion = new QuickUnion(noCities);

            foreach (var item in existingRoads)
            {
                // adjust the value of id from 0 to N - 1
                quickUnion.Union(item[0] - 1, item[1] - 1);
            }

            int count = quickUnion.GetCount();

            var newRoadMap = new Dictionary <int, List <int> >();

            foreach (int[] item in roadWithCost)
            {
                var id1      = item[0] - 1;
                var id2      = item[1] - 1;
                var roadCost = item[2];

                var newId = id1 * 50 + id2;
                if (!newRoadMap.ContainsKey(roadCost))
                {
                    newRoadMap.Add(roadCost, new List <int>());
                }

                newRoadMap[roadCost].Add(newId);
            }

            var costs = newRoadMap.Keys.ToArray();

            Array.Sort(costs);

            var length    = costs.Length;
            var totalCost = 0;

            for (int i = 0; i < length; i++)
            {
                var current = costs[i];
                var ids     = newRoadMap[current];
                foreach (var id in ids)
                {
                    var id1 = id % 50;
                    var id2 = id / 50;

                    var connected = quickUnion.Connected(id1, id2);
                    if (connected)
                    {
                        continue;
                    }

                    totalCost += current;
                    quickUnion.Union(id1, id2); // Union, not Connected
                }
            }

            if (quickUnion.GetCount() > 1)
            {
                return(-1);
            }

            return(totalCost);
        }