//graph.cpp -- implement file.//2011-09-25-14.31 -- 2011-09-25-15.58//2011-09-25-18.16 -- 2011-09-25-20.00//2011-09-26-17.20 -- 2011-09-26-18.04//2011-09-26-19.19 -- 2011-09-26-20.00//2011-09-27-09.06 -- 2011-09-27-09.57template<class T>void Graph<T> ::getIncreasingOrder (unsigned int currentIndex){static T * duplicateOfResidualFlowOfALine = new T[m_totalNumOfVertexes] ;//Initialize duplicateOfResidualFlowOfALine.for (unsigned int i = 0; i < m_totalNumOfVertexes; ++i){duplicateOfResidualFlowOfALine[i] = m_residualFlow[currentIndex][i] ;}//Initialize m_currentVertexAdjoinsTo in normal order.for (unsigned int i = 0; i < m_totalNumOfVertexes; ++i){m_currentVertexAdjoinsTo[i] = i ;}//Sorting duplicateOfResidualFlowOfALine in increasing order.//As a result of, m_currentVertexAdjoinsTo will be sorted as duplicateOfResidualFlowOfALine in increasing order.unsigned int i = 1 ;while (i < m_totalNumOfVertexes){T tempResidual = duplicateOfResidualFlowOfALine[i] ;unsigned int tempVertex = m_currentVertexAdjoinsTo[i] ;unsigned int j = i ;while (j != 0 && tempResidual < duplicateOfResidualFlowOfALine[j - 1]){duplicateOfResidualFlowOfALine[j] = duplicateOfResidualFlowOfALine[j - 1] ;m_currentVertexAdjoinsTo[j] = m_currentVertexAdjoinsTo[j - 1] ;--j ;}duplicateOfResidualFlowOfALine[j] = tempResidual ;m_currentVertexAdjoinsTo[j] = tempVertex ;++i ;}}template<class T>bool Graph<T> ::m_existsAAugmentingPath (T * const pMinFlows){m_color[m_startIndex] = Color_Gray ;m_parent[m_startIndex] = HasNotAParent ;queue<int> q ;q.push(m_startIndex) ;T minFlow = Infinity ;while (!q.empty()){unsigned int topIndex = q.front() ;//After called getIncreasingOrder(topIndex), m_currentVertexAdjoinsTo[] will be sorted.//m_currentVertexAdjoinsTo[0] <= m_currentVertexAdjoinsTo[1] <= ... <= m_currentVertexAdjoinsTo[m_totalNumOfVertexes - 1].//So will select a shortest path every time, this is very important for this algorithm.getIncreasingOrder(topIndex) ;q.pop() ;for (unsigned int index = 0; index < m_totalNumOfVertexes; ++index){if (Color_White == m_color[m_currentVertexAdjoinsTo[index]] && m_residualFlow[topIndex][m_currentVertexAdjoinsTo[index]] > 0){if (m_residualFlow[topIndex][m_currentVertexAdjoinsTo[index]] < minFlow){minFlow = m_residualFlow[topIndex][m_currentVertexAdjoinsTo[index]] ;}m_parent[m_currentVertexAdjoinsTo[index]] = topIndex ;m_color[m_currentVertexAdjoinsTo[index]] = Color_Gray ;q.push(m_currentVertexAdjoinsTo[index]) ;}}m_color[topIndex] = Color_Black ;}//Record the min flow.*pMinFlows = minFlow ;//Test if has visited V[endIndex], if so mean there exists a path from V[startIndex] to V[endIndex] in the residual net.if (Color_Black == m_color[m_endIndex])return true ;elsereturn false ;}//Start index must be 0 and end index must be numOfVertexes - 1.template<class T>Graph<T> ::Graph (unsigned int numOfVertexes):m_selectedFlow(NULL),m_residualFlow(NULL),m_currentVertexAdjoinsTo(NULL),m_color(NULL),m_currentNumOfVertexes(0),m_totalNumOfVertexes(numOfVertexes),HasNotAParent(numOfVertexes + 1),m_startIndex(0),m_endIndex(numOfVertexes - 1){if (0 == numOfVertexes)throw std ::runtime_error("Empty graph is invalid.") ;//Allocate memory and initialize elements.m_selectedFlow = new T *[numOfVertexes] ;for (unsigned int i = 0; i < numOfVertexes; ++i){m_selectedFlow[i] = new T[numOfVertexes] ;}for (unsigned int i = 0; i < numOfVertexes; ++i){for (unsigned int j = 0; j < numOfVertexes; ++j){m_selectedFlow[i][j] = 0 ;}}m_residualFlow = new T*[numOfVertexes] ;for (unsigned int i = 0; i < numOfVertexes; ++i){m_residualFlow[i] = new T[numOfVertexes] ;}for (unsigned int i = 0; i < numOfVertexes; ++i){for (unsigned int j = 0; j < numOfVertexes; ++j){m_residualFlow[i][j] = 0 ;}}//Initialize m_currentVertexAdjoinsTo at runtime.m_currentVertexAdjoinsTo = new unsigned int[numOfVertexes] ;m_color = new Color[numOfVertexes] ;for (unsigned int i = 0; i < numOfVertexes; ++i){m_color[i] = Color_White ;}m_parent = new unsigned int[numOfVertexes] ;for (unsigned int i = 0; i < numOfVertexes; ++i){m_parent[i] = HasNotAParent ;}}template<class T>bool Graph<T> :: importAVertex( const vector<T> &indexAdjoinsTo, const vector<T> &residualFlowAdjoinsTo){if (m_currentNumOfVertexes == m_totalNumOfVertexes || indexAdjoinsTo.size() != residualFlowAdjoinsTo.size())return false ;vector<T> ::const_iterator iterIndex = indexAdjoinsTo.begin() ;vector<T> ::const_iterator iterResidual = residualFlowAdjoinsTo.begin() ;while (iterIndex != indexAdjoinsTo.end()){m_residualFlow[m_currentNumOfVertexes][*iterIndex] = *iterResidual ;//Its reversed edge's residual flow had been setted as 0 when ctor was calling.++iterIndex ;++iterResidual ;}++m_currentNumOfVertexes ;return true ;}template<class T>void Graph<T> ::calculateMaxFlow (void){T minFlow ;while (m_existsAAugmentingPath(&minFlow)){//There exists a path from V[startIndex] to V[endIndex] in the residual net.//Updata m_selectedFlow and m_residualFlow along breadth first search path.unsigned int currentIndex = m_endIndex ;unsigned int parentIndex = m_parent[m_endIndex] ;while (parentIndex != HasNotAParent){m_selectedFlow[parentIndex][currentIndex] += minFlow ;m_residualFlow[parentIndex][currentIndex] -= minFlow ;m_residualFlow[currentIndex][parentIndex] += minFlow ;currentIndex = parentIndex ;parentIndex = m_parent[currentIndex] ;}//Reset parentIndex and m_color for next calling.for (unsigned int i = 0; i < m_totalNumOfVertexes; ++i){m_parent[i] = HasNotAParent ;}for (unsigned int i = 0; i < m_totalNumOfVertexes; ++i){m_color[i] = Color_White ;}}}template<class T>T Graph<T> ::maxFlow (void) const{//Calculate all the flows start from V[startIndex], it's the flows between startIndex and endIndex.T flows = 0 ;for (unsigned int i = 0; i < m_totalNumOfVertexes; ++i){//If there isn't a path between V[startIndex] and V[i],//m_selectedFlow[startIndex][i] is 0.flows += m_selectedFlow[m_startIndex][i] ;}return flows ;}template<class T>void Graph<T> ::printEveryFlow (void) const{for (unsigned int i = 0; i < m_totalNumOfVertexes; ++i){for (unsigned int j = 0; j < m_totalNumOfVertexes; ++j){if (m_selectedFlow[i][j] > 0){std ::cout << "V[" << i << "] ->[" << j << "]: " << m_selectedFlow[i][j] << std ::endl ;}}}}template<class T>void Graph<T> ::printGraph (void) const{if (m_currentNumOfVertexes < m_totalNumOfVertexes){std ::cout << "Not all vertexes have been inported, can't print the graph." ;return ;}for (unsigned int i = 0; i < m_totalNumOfVertexes; ++i){for (unsigned int j = 0; j < m_totalNumOfVertexes; ++j){std ::cout << m_selectedFlow[i][j] << " " ;}std ::cout << std ::endl ;}for (unsigned int i = 0; i < m_totalNumOfVertexes; ++i){for (unsigned int j = 0; j < m_totalNumOfVertexes; ++j){std ::cout << m_residualFlow[i][j] << " " ;}std ::cout << std ::endl ;}}