/// <summary>
        /// Computes the minimum spanning tree on a DT with given weights.
        /// </summary>
        /// <param name="cdt"></param>
        /// <param name="weights"></param>
        /// <returns></returns>
        static internal List<CdtEdge> GetMstOnCdt(Cdt cdt, Func<CdtEdge, double> weights) {
            var siteArray = cdt.PointsToSites.Values.ToArray();
            var siteIndex = new Dictionary<CdtSite, int>();
            for (int i = 0; i < siteArray.Length; i++)
                siteIndex[siteArray[i]] = i;

            Dictionary<IntPair, CdtEdge> intPairsToCdtEdges = GetEdges(siteArray, siteIndex);

            var graph = new BasicGraph<IEdge>( intPairsToCdtEdges.Keys, siteArray.Length);

            var mstOnBasicGraph = new MinimumSpanningTreeByPrim(graph, intPair => weights(intPairsToCdtEdges[(IntPair)intPair]), 0);

            return new List<CdtEdge>(mstOnBasicGraph.GetTreeEdges().Select(e=>intPairsToCdtEdges[(IntPair)e]));
        }
        /// <summary>
        /// Computes the minimum spanning tree on a set of edges
        /// </summary>
        /// <param name="proximityEdges">list of tuples, each representing an edge with: nodeId1, nodeId2, t(overlapFactor), ideal distance, edge weight.</param>
        /// <param name="sizeId"></param>
        /// <returns></returns>
        static internal List<Tuple<int, int, double, double, double>> GetMstOnTuple(List<Tuple<int,int,double,double,double>> proximityEdges, int sizeId) {
            if (proximityEdges.Count == 0)
            {
                return null;
            }
            var intPairs = proximityEdges.Select(t => new IntPair(t.Item1, t.Item2)).ToArray();
            var weighting = new Dictionary<IntPair, Tuple<int, int, double, double, double>>(intPairs.Count());
            for (int i = 0; i < proximityEdges.Count; i++) {
                weighting[intPairs[i]] = proximityEdges[i];
            }
            var graph = new BasicGraph<IEdge>(intPairs, sizeId);

            var mstOnBasicGraph = new MinimumSpanningTreeByPrim(graph, intPair => weighting[(IntPair)intPair].Item5, intPairs[0].First);

            List<Tuple<int, int, double, double, double>> treeEdges = mstOnBasicGraph.GetTreeEdges().Select(e => weighting[(IntPair) e]).ToList();
            return treeEdges;
        }