// The Function That Calculates The Minimum Spanning Tree For The Graph
        // Its Only Parameter Is The List Of Distinct Colors
        public void MinSpanningTree(List <RGBPixel> LoD)
        {
            // Using A Priority Queue So That The Edges Are
            // Sorted According To Their Weights In Ascending Order
            // The Priority Queue Contains The Number Of Vertices (LoD.Count)
            FastPriorityQueue <PQNode> PQ = new FastPriorityQueue <PQNode>(LoD.Count);

            // An Array That Contains Each Node (color)
            // And A Pointer To That Node's Parent
            PQNode[] PQNode = new PQNode[LoD.Count];

            // Initialising The First Node In The Array
            // Its Parent Is Null
            PQNode[0] = new PQNode(LoD[0], null);
            // Inserting That First Node Into The Priority Queue
            // With A Value of 0
            PQ.Enqueue(PQNode[0], 0);

            float weight;

            // For Each Vertex (Minus The Already Added One),
            // Insert That Vertex Into The Array
            // With Parent = null, Then Insert It Into The PQ
            // With Values = Infinity
            for (int i = 1; i < LoD.Count; i++)
            {
                PQNode[i] = new PQNode(LoD[i], null);
                PQ.Enqueue(PQNode[i], int.MaxValue);
            }

            // Looping Until The Priority Queue Is Empty
            while (PQ.Count != 0)
            {
                // Dequeuing The First (Minimum) Element
                // From The PQ
                PQNode Minimum = PQ.Dequeue();

                // Checking If The Minimum Element Is The Root Node Or Not
                // (Only The Root Node Has A Null Parent In The First Iteration)
                if (Minimum.Parent != null)
                {
                    Edge edge;
                    edge.src    = Minimum.currentVertex;
                    edge.dest   = (RGBPixel)Minimum.Parent;
                    edge.weight = (Minimum.currentWeight);

                    MST.Add(edge);         // Add the minimum weight to the MST.
                    MSTSum += edge.weight; // Add The Edge's Weight To The MST Sum
                }

                // We Have To Modify The Values Of The PQ
                // Each Time
                foreach (var node in PQ)
                {
                    // Calculating The Weight Difference Between The Current Node
                    // And The Minimum Node
                    weight = WeightDifference(node, Minimum);

                    // If That Weight Difference Is Less Than The Node's Current Weight
                    // Then The Minimum Node Becomes The Parent Of That Node
                    // And We Adjust That Node's Weight To The Weight Difference
                    // By Updating The PQ
                    if (weight < node.currentWeight)
                    {
                        node.Parent = Minimum.currentVertex;
                        PQ.UpdatePriority(node, weight);
                    }
                }
            }
        }
        }             //get_distincit

        public static void grph(int CLUS)// graph construction and getting edges that will be cut that take number of clusters
        {
            /*
             * Total complexty = O (E log (k))
             *           --where E is the number of edges and K is the number of clusters wanted to cut
             */
            float min = 10000000, newedge;
            //min is minimum value that take from moving from exesting node to another node, newedge is edge between exesting node to another node
            int k = 0, count = nodes.Count;               //k is the index of minimum node that i would start in next time

            bool[] vstd = new bool[16777216];             //to check if node has been visited before (get values between it and all another none visited nodes)
            VX = new Dictionary <GRAPH, float>();         // initialize th helper of periority_queue
            H  = new FastPriorityQueue <GRAPH>(CLUS - 1); //initialize periority_queue

            for (int i = k; ;)                            //first loop to move in distincit node
            {
                bool ch = false;                          // if it still false then i can't go anywhere because all nodes have been visited
                if (vstd[nodes[i]])
                {
                    continue;                   // if the node that i stand in is visited then continue
                }
                vstd[nodes[i]] = true;          //this not is not visited before then make it as visited
                min            = 10000000;      // give minimum every time very large value
                for (int j = 0; j < count; j++) //second loop to move in distincit node
                {
                    if (vstd[nodes[j]])
                    {
                        continue; //if the node that i stand in is visited then continue
                    }
                    ch = true;    //then it i found another node to move in
                    byte[] b = BitConverter.GetBytes(nodes[i]), bb = BitConverter.GetBytes(nodes[j]);
                    // convert the shifted integer to red and green and blue
                    newedge = (((b[0] - bb[0]) * (b[0] - bb[0])) + ((b[1] - bb[1]) * (b[1] - bb[1])) + ((b[2] - bb[2]) * (b[2] - bb[2])));
                    //calculate the edge between to nodes
                    if (newedge < min)                //if the edge i have less than minimum then
                    {
                        min = newedge;                //make the minimum is newedge
                        k   = j;                      //and save its index to start from it the next time
                    }
                    if (MST[j].edge < min)            // if the edge that is already saved is less than minimum then
                    {
                        min = MST[j].edge;            //make the minimum is saved edge
                        k   = j;                      //and save its index to start from it the next time
                    }
                    if (newedge < (float)MST[j].edge) // if the calculated edge before is larger than the newly calculated edge then
                    {
                        MST[j].edge = newedge;        //then replace the calculaed edge with the new minimum edge
                        MST[j].from = nodes[i];       //and change from where it comes
                    }
                }
                i = k;                                      //K is the minimum index that i will start the loop with
                if (ch == false)                            // then i cant go to any node again because all nodes have been visited then choose the cutted edges
                {
                    GRAPH T = new GRAPH();                  //temp to delete the deleted edge from dictionary as it is deleted from periority_queue
                    for (int y = 1; y < MST.Count; y++)     //move in all Minimum spanning tree
                    {
                        if (H.Count < CLUS - 1)             // if the periority_queue is not filled with required number of clusters then
                        {
                            H.Enqueue(MST[y], MST[y].edge); // add in periority_queue with complexty O(log K) k is the wanted number of clusters
                            VX.Add(MST[y], MST[y].edge);    // add in the dictionary this edge
                        }
                        else//if the periority_queue is  filled with required number of clusters then
                        {
                            if (H.First.edge < MST[y].edge)     //check if the edge that i stand is larger than the top of queue that contain the smallest edge
                            {
                                T = H.Dequeue();                //pop the smallest from the queue
                                VX.Remove(T);                   //remove also this node from dictionary
                                H.Enqueue(MST[y], MST[y].edge); //enqueue the new large node with the new large edge with complexty O(log K)
                                VX.Add(MST[y], MST[y].edge);    //add the new large node with the new large edge
                            }
                        }
                    }
                }
                if (!ch)
                {
                    break;      //if i can't go anywhere then break
                }
            }//main loop
             /* this to get cost of minimum spanning tree*/

            /*   double sum = 0;
             * for (int i = 1; i < MST.Count; i++)
             * {
             *     sum += Math.Sqrt(MST[i].edge);
             * }
             * MessageBox.Show(sum.ToString());*/
        }