void SwapWithParent(int i)
        {
            HeapElem parent = A[i >> 1];

            PutAtI(i >> 1, A[i]);
            PutAtI(i, parent);
        }
        internal void Enqueue(int o, double priority) {
            //System.Diagnostics.Debug.WriteLine("insert "+ o.ToString() + " with pr "+ priority.ToString());

            heapSize++;
            int i = heapSize;
       
            System.Diagnostics.Debug.Assert(cache[o] == null);
            A[i] = cache[o] =new HeapElem(i, priority, o);
            while (i > 1 && A[i >> 1].priority.CompareTo(priority) > 0) {
                SwapWithParent(i);
                i >>= 1;
            }
       
        }
        internal void Enqueue(int o, double priority)
        {
            //System.Diagnostics.Debug.WriteLine("insert "+ o.ToString() + " with pr "+ priority.ToString());

            heapSize++;
            int i = heapSize;

            System.Diagnostics.Debug.Assert(cache[o] == null);
            A[i] = cache[o] = new HeapElem(i, priority, o);
            while (i > 1 && A[i >> 1].priority.CompareTo(priority) > 0)
            {
                SwapWithParent(i);
                i >>= 1;
            }
        }
        internal void DecreasePriority(int o, double newPriority)
        {
            //System.Diagnostics.Debug.WriteLine("delcrease "+ o.ToString()+" to "+ newPriority.ToString());

            HeapElem h = cache[o];

            h.priority = newPriority;
            int i = h.indexToA;

            while (i > 1)
            {
                if (A[i].priority.CompareTo(A[i >> 1].priority) < 0)
                {
                    SwapWithParent(i);
                }
                else
                {
                    break;
                }
                i >>= 1;
            }
        }
 void PutAtI(int i, HeapElem h)
 {
     A[i]       = h;
     h.indexToA = i;
 }
 void PutAtI(int i, HeapElem h) {
     A[i] = h;
     h.indexToA = i;
 }