void prim(Wgraph& wg, Wgraph& mstree) { // Find a minimum spanning tree of wg using Prim's // algorithm and return its in mstree. vertex u,v; edge e; edge *cheap = new edge[wg.n()+1]; //Dheap nheap(wg.n(),2); Dheap nheap(wg.n(),2+wg.m()/wg.n()); nheap.clearStats(); for (e = wg.firstAt(1); e != 0; e = wg.nextAt(1,e)) { u = wg.mate(1,e); nheap.insert(u,wg.weight(e)); cheap[u] = e; } while (!nheap.empty()) { u = nheap.deletemin(); e = mstree.join(wg.left(cheap[u]),wg.right(cheap[u])); mstree.setWeight(e,wg.weight(cheap[u])); for (e = wg.firstAt(u); e != 0; e = wg.nextAt(u,e)) { v = wg.mate(u,e); if (nheap.member(v) && wg.weight(e) < nheap.key(v)) { nheap.changekey(v,wg.weight(e)); cheap[v] = e; } else if (!nheap.member(v) && mstree.firstAt(v) == 0) { nheap.insert(v,wg.weight(e)); cheap[v] = e; } } } //string s; //cerr << nheap.stats2string(s) << endl; delete [] cheap; }
heap_t * build_maxheap(int *A, size_t len) { heap_t *hp; size_t i; hp = nheap(A, len); for (i = hp->size >> 1 ; i; i--) max_heapify(hp, i); return hp; }
/** Find a shortest path tree using Dijkstra's algorithm. * @param g is a directed graph with edge lengths * @param s is the source vertex for the shortest path tree computation; * if s=0, paths are computed from an imaginary extra vertex with a * zero length edge to every other vertex * @param pEdge is an array of parent pointers; on return pEdge[u] is the * number of the edge connecting u to its parent in the shortest path tree * @param d is array of distances; on return d[u] is the shortest path * distance from s to u * @return true on success, false if not all vertices can be reached */ bool dijkstra(Wdigraph& g, vertex s, edge* pEdge, edgeLength* d) { Dheap<int> nheap(g.n(),4); for (vertex v = 1; v <= g.n(); v++) { pEdge[v] = 0; d[v] = INT_MAX; } d[s] = 0; nheap.insert(s,0); int cnt = 0; while (!nheap.empty()) { vertex v = nheap.deletemin(); cnt++; for (edge e = g.firstOut(v); e != 0; e = g.nextOut(v,e)) { vertex w = g.head(e); if (d[w] > d[v] + g.length(e)) { d[w] = d[v] + g.length(e); pEdge[w] = e; if (nheap.member(w)) nheap.changekey(w,d[w]); else nheap.insert(w,d[w]); } } } return cnt == g.n(); }
/** Find a minimum spanning tree using Prim's algorithm. * This version uses a Fibonacci heap * @param wg is a weighted graph * @param mstree is a second weighted graph data structure in which the * the result is to be returned; it is assumed to have no edges */ void primF(Wgraph& wg, Wgraph& mstree) { vertex u,v; edge e; edge* cheap = new edge[wg.n()+1]; Fheaps nheap(wg.n()); fheap root; bool *inHeap = new bool[wg.n()+1]; // inHeap[u]=true if u is in heap int numInHeap = 0; for (u = 1; u <= wg.n(); u++) inHeap[u] = false; e = wg.firstAt(1); if (e == 0) return; root = wg.mate(1,e); do { u = wg.mate(1,e); root = nheap.insert(u,root,wg.weight(e)); cheap[u] = e; inHeap[u] = true; numInHeap++; e = wg.nextAt(1,e); } while (e != 0); while (numInHeap > 0) { u = root; root = nheap.deletemin(root); inHeap[u] = false; numInHeap--; e = mstree.join(wg.left(cheap[u]),wg.right(cheap[u])); mstree.setWeight(e,wg.weight(cheap[u])); for (e = wg.firstAt(u); e != 0; e = wg.nextAt(u,e)) { v = wg.mate(u,e); if (inHeap[v] && wg.weight(e) < nheap.key(v)) { root = nheap.decreasekey(v,nheap.key(v) - wg.weight(e),root); cheap[v] = e; } else if (!inHeap[v] && mstree.firstAt(v) == 0) { root = nheap.insert(v,root,wg.weight(e)); cheap[v] = e; inHeap[v] = true; numInHeap++; } } } delete [] cheap; delete [] inHeap; }