diff --git a/project5.cc b/project5.cc index 611674a..53951cc 100644 --- a/project5.cc +++ b/project5.cc @@ -18,48 +18,48 @@ using namespace std; * check if we are at the end of the file */ bool eof() { - char c; - std::cin >> c; - // if the fie is ended, return true - if (std::cin.eof()) { - return true; - } else { - // if the file contains more data, return the previously gotten - // data to cin - std::cin.unget(); - return false; - } + char c; + std::cin >> c; + // if the fie is ended, return true + if (std::cin.eof()) { + return true; + } else { + // if the file contains more data, return the previously gotten + // data to cin + std::cin.unget(); + return false; + } } int main(int argc, char *argv[]) { - // Repeatedly read input from standard input - while (!eof()) { - // create a new graph for each loop, which will read all of the - // corresponding data per graph - Province theProvince(cin); + // Repeatedly read input from standard input + while (!eof()) { + // create a new graph for each loop, which will read all of the + // corresponding data per graph + Province theProvince(cin); - std::cout << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << "---------------- New DataSet: ------------------" << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << "---------------- New DataSet: ------------------" << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << std::endl; - theProvince.printAll(0, cout); + theProvince.printAll(0, cout); - theProvince.printShortestPath(std::cout); + theProvince.printShortestPath(std::cout); - std::cout << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << std::endl; - theProvince.minSpan(std::cout); + theProvince.minSpan(std::cout); - std::cout << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << std::endl; - } + } } diff --git a/province.cc b/province.cc index b9c9e1d..eb09948 100644 --- a/province.cc +++ b/province.cc @@ -92,32 +92,32 @@ void Province::printAll(int start, std::ostream & output) { // Add current town's(vertex's) unscheduled neighbors to the queue for (Town::RoadList::iterator neighbor = _towns[current]._roads.begin(); neighbor != _towns[current]._roads.end(); neighbor++) { - std::string neighborName = _towns[neighbor->_head]._name; + std::string neighborName = _towns[neighbor->_head]._name; - output << " "; - output << neighborName << " " << neighbor->_length << " mi"; + output << " "; + output << neighborName << " " << neighbor->_length << " mi"; - // if the type is bridge, then add to output - if (neighbor ->_isBridge) { - output << " via bridge"; - } + // if the type is bridge, then add to output + if (neighbor ->_isBridge) { + output << " via bridge"; + } - output << endl; + output << endl; - int head = neighbor ->_head; + int head = neighbor ->_head; - // If neighbour is not scheduled, add neighbor to the queue - if (!scheduled[head]) { - toVisit.push(head); - scheduled[head] = true; - } + // If neighbour is not scheduled, add neighbor to the queue + if (!scheduled[head]) { + toVisit.push(head); + scheduled[head] = true; } + } } output << endl << endl; } int Province::smallest(double dist[], std::list toVisit, - int numTowns) const { + int numTowns) const { int smallest = toVisit.front(); if (toVisit.size() > 1) { @@ -140,85 +140,85 @@ int Province::smallest(double dist[], std::list toVisit, */ void Province::printShortestPath(std::ostream & output) const { - // if there is only one town only one town - if (_numberOfTowns == 1) { - output << "There is only one town, so the provincial " - << "officials have no need of efficient routes!"; - return; - } - - output << "The shortest routes from " + _towns[0]._name; - output << " are:" << std::endl << std::endl; - - // keeps track of the index of the predecessor to each - // town(vertex) n on the shortest path to n - int prev[_numberOfTowns]; - - // queue to keep track of which town(vertex) to visit next - list toVisit; + // if there is only one town only one town + if (_numberOfTowns == 1) { + output << "There is only one town, so the provincial " + << "officials have no need of efficient routes!"; + return; + } - // keeps track of the distance from the capital to each town - // following the shortest path - double dist[_numberOfTowns]; + output << "The shortest routes from " + _towns[0]._name; + output << " are:" << std::endl << std::endl; + // keeps track of the index of the predecessor to each + // town(vertex) n on the shortest path to n + int prev[_numberOfTowns]; - // set defaults for dist, prev, and add all vertices to toVisit - for (int i = 0; i < _numberOfTowns; i++) { - dist[i] = DBL_MAX; - toVisit.push_back(i); - } + // queue to keep track of which town(vertex) to visit next + list toVisit; - // distance from the capital to the capital is zero - dist[0] = 0.0; + // keeps track of the distance from the capital to each town + // following the shortest path + double dist[_numberOfTowns]; - while (!toVisit.empty()) { - int smallestIndex = smallest(dist, toVisit, _numberOfTowns); - toVisit.remove(smallestIndex); + // set defaults for dist, prev, and add all vertices to toVisit + for (int i = 0; i < _numberOfTowns; i++) { + dist[i] = DBL_MAX; + toVisit.push_back(i); + } - // Add current vertex's neighbors to the queue - for (Town::RoadList::iterator neighbor = - _towns[smallestIndex]._roads.begin(); - neighbor != _towns[smallestIndex]._roads.end(); neighbor++) { - // new distance needed for testing - double newDist = dist[smallestIndex] + neighbor->_length; + // distance from the capital to the capital is zero + dist[0] = 0.0; - // if new dist is smaller, replace the old one, and - // update the corresponding entry in prev - if (newDist < dist[neighbor->_head]) { - dist[neighbor->_head] = newDist; - prev[neighbor->_head] = smallestIndex; - } - } - } + while (!toVisit.empty()) { + int smallestIndex = smallest(dist, toVisit, _numberOfTowns); + + toVisit.remove(smallestIndex); + + // Add current vertex's neighbors to the queue + for (Town::RoadList::iterator neighbor = + _towns[smallestIndex]._roads.begin(); + neighbor != _towns[smallestIndex]._roads.end(); neighbor++) { + // new distance needed for testing + double newDist = dist[smallestIndex] + neighbor->_length; + + // if new dist is smaller, replace the old one, and + // update the corresponding entry in prev + if (newDist < dist[neighbor->_head]) { + dist[neighbor->_head] = newDist; + prev[neighbor->_head] = smallestIndex; + } + } + } - // print out the data for each non capital town - for (int i = 1; i < _numberOfTowns; i++) { - output << " " << "The shortest route from " + _towns[0]._name; - output << " to " + _towns[i]._name + " is " << dist[i]; - output << " mi:" << std::endl; + // print out the data for each non capital town + for (int i = 1; i < _numberOfTowns; i++) { + output << " " << "The shortest route from " + _towns[0]._name; + output << " to " + _towns[i]._name + " is " << dist[i]; + output << " mi:" << std::endl; - // stack to hold the path to the town at index i - std::stack predecessors; + // stack to hold the path to the town at index i + std::stack predecessors; - // add town at i to stack - int predecessor = i; - predecessors.push(i); + // add town at i to stack + int predecessor = i; + predecessors.push(i); - // follow the links in prev until we get to the capital, - // adding each town to the predecessor stack - while (predecessor != 0) { - predecessor = prev[predecessor]; - predecessors.push(predecessor); - } + // follow the links in prev until we get to the capital, + // adding each town to the predecessor stack + while (predecessor != 0) { + predecessor = prev[predecessor]; + predecessors.push(predecessor); + } - // print out the names for each entry in the stack - while (!predecessors.empty()) { - output << " " << _towns[predecessors.top()]._name; - output << std::endl; - predecessors.pop(); - } + // print out the names for each entry in the stack + while (!predecessors.empty()) { + output << " " << _towns[predecessors.top()]._name; + output << std::endl; + predecessors.pop(); } + } } /** @@ -227,7 +227,7 @@ void Province::printShortestPath(std::ostream & output) const { * @return True if road1 is shorter in length than road 2 */ bool Province::Road::operator < (Road road2) const { - return this->_length < road2._length; + return this->_length < road2._length; } /** @@ -235,64 +235,64 @@ bool Province::Road::operator < (Road road2) const { */ void Province::minSpan(std::ostream & output) const { - // if only one town - if (_numberOfTowns == 1) { - output << "There is only one town, so the province " - << "does not need to upgrade any roads!"; - return; - } + // if only one town + if (_numberOfTowns == 1) { + output << "There is only one town, so the province " + << "does not need to upgrade any roads!"; + return; + } - list roads; - vector minSpanTree; - vector higher; + list roads; + vector minSpanTree; + vector higher; - // Initialize a numComponent value for each town to 0 - int numComponent[_numberOfTowns]; - for (int i = 0; i < _numberOfTowns; i++) { - numComponent[i] = 0; - } + // Initialize a numComponent value for each town to 0 + int numComponent[_numberOfTowns]; + for (int i = 0; i < _numberOfTowns; i++) { + numComponent[i] = 0; + } - // Add all roads to list of roads - for (int i = 0; i < _numberOfRoads; i++) { - roads.push_back(_roads[i]); - } - - // Sort list of roads by length - roads.sort(); - - int compNum = 0; // Used to determine if edge forms a cycle - while (minSpanTree.size() < _numberOfTowns - 1) { - Road minRoad = roads.front(); - roads.pop_front(); - - // Both towns have component number 0 - if (numComponent[minRoad._head] == 0 && - numComponent[minRoad._tail] == 0) { - minSpanTree.push_back(minRoad); - compNum++; - numComponent[minRoad._head] = compNum; - numComponent[minRoad._tail] = compNum; - - // Only one town has component number 0 - } else if (numComponent[minRoad._head] == 0) { - minSpanTree.push_back(minRoad); - numComponent[minRoad._head] = numComponent[minRoad._tail]; - - // Other town has component number 0 - } else if (numComponent[minRoad._tail] == 0) { - minSpanTree.push_back(minRoad); - numComponent[minRoad._tail] = numComponent[minRoad._head]; - - // If component number of one town is less than other town - } else if (numComponent[minRoad._head] < - numComponent[minRoad._tail]) { - minSpanTree.push_back(minRoad); - higher.push_back(minRoad._tail); + // Add all roads to list of roads + for (int i = 0; i < _numberOfRoads; i++) { + roads.push_back(_roads[i]); + } - // Set all higher road components to value of lower - for (int i = 0; i < higher.size(); i++) { - higher[i] = numComponent[minRoad._head]; - } + // Sort list of roads by length + roads.sort(); + + int compNum = 0; // Used to determine if edge forms a cycle + while (minSpanTree.size() < _numberOfTowns - 1) { + Road minRoad = roads.front(); + roads.pop_front(); + + // Both towns have component number 0 + if (numComponent[minRoad._head] == 0 && + numComponent[minRoad._tail] == 0) { + minSpanTree.push_back(minRoad); + compNum++; + numComponent[minRoad._head] = compNum; + numComponent[minRoad._tail] = compNum; + + // Only one town has component number 0 + } else if (numComponent[minRoad._head] == 0) { + minSpanTree.push_back(minRoad); + numComponent[minRoad._head] = numComponent[minRoad._tail]; + + // Other town has component number 0 + } else if (numComponent[minRoad._tail] == 0) { + minSpanTree.push_back(minRoad); + numComponent[minRoad._tail] = numComponent[minRoad._head]; + + // If component number of one town is less than other town + } else if (numComponent[minRoad._head] < + numComponent[minRoad._tail]) { + minSpanTree.push_back(minRoad); + higher.push_back(minRoad._tail); + + // Set all higher road components to value of lower + for (int i = 0; i < higher.size(); i++) { + higher[i] = numComponent[minRoad._head]; + } // If component number of other town is less than other town } else if (numComponent[minRoad._head] > @@ -302,19 +302,19 @@ void Province::minSpan(std::ostream & output) const { // Set all higher road components to value of lower for (int i = 0; i < higher.size(); i++) { - higher[i] = numComponent[minRoad._tail]; + higher[i] = numComponent[minRoad._tail]; } - } - } + } + } - output << "The road upgrading goal can be achieved at minimal cost by upgrading:"; - output << std::endl << std::endl; - - // Print names of towns in minimum spanning tree of province - for (int i = 0; i < minSpanTree.size(); i++) { - output << " "; - output << _towns[minSpanTree[i]._head]._name; - output << " to "; - output << _towns[minSpanTree[i]._tail]._name << std::endl; - } + output << "The road upgrading goal can be achieved at minimal cost by upgrading:"; + output << std::endl << std::endl; + + // Print names of towns in minimum spanning tree of province + for (int i = 0; i < minSpanTree.size(); i++) { + output << " "; + output << _towns[minSpanTree[i]._head]._name; + output << " to "; + output << _towns[minSpanTree[i]._tail]._name << std::endl; + } } diff --git a/province.h b/province.h index 5b231ef..a5ce1c7 100644 --- a/province.h +++ b/province.h @@ -14,90 +14,90 @@ /** - * towns connected by roads - */ +* towns connected by roads +*/ class Province { public: - /** - * Constructor - * @param source Input data for province - */ - Province(std::istream & source); - - /** - * Print towns and roads in province in breadth-first search order - * @param output Stream to print data to - */ - void printAll(int start, std::ostream & output); - void printShortestPath(std::ostream & output) const; + /** + * Constructor + * @param source Input data for province + */ + Province(std::istream & source); + + /** + * Print towns and roads in province in breadth-first search order + * @param output Stream to print data to + */ + void printAll(int start, std::ostream & output); + void printShortestPath(std::ostream & output) const; - /** - * Find shortest path from one town to another - */ - void findShortestPath(); + /** + * Find shortest path from one town to another + */ + void findShortestPath(); - void minSpan(std::ostream & output) const; + void minSpan(std::ostream & output) const; - void removeBridges(std::ostream & output) const; + void removeBridges(std::ostream & output) const; - void articulationPoints(std::ostream & output) const; + void articulationPoints(std::ostream & output) const; - void dfs(std::vector & dfsTowns) const; + void dfs(std::vector & dfsTowns) const; - /** - * Destructor - */ - ~Province() {} + /** + * Destructor + */ + ~Province() {} private: - int smallest(double dist [], std::list toVisit, int numTowns) const; - std::vector bfs(int start) const; - void dfsAux(int current, std::vector & dfsTowns, bool visited []) const; - - /** - * Road - * Contains index of originating town, whether or not is bridge, - * and length - */ - class Road - { - public: - - /* - * Constructor - * @param head Index in vertex array of originating town - * @param isBridge Whether or not the road is a bridge - * @param length Length of the road in miles - */ - Road(int head, int tail, char isBridge, double length) - : _head(head), _tail(tail), _isBridge(isBridge), _length(length) - {} - - int _head; // Index of originating town in vertex array - int _tail; - char _isBridge; - double _length; - - bool operator < (Road road2) const; - }; - - /** - * Town - * Contains name and a list of roads that connect to it - */ - class Town - { - public: // consider making some of these private (RoadList) - std::string _name; - typedef std::list RoadList; - RoadList _roads; - }; - - int _numberOfTowns; - int _numberOfRoads; - Town *_towns; - std::vector _roads; + int smallest(double dist [], std::list toVisit, int numTowns) const; + std::vector bfs(int start) const; + void dfsAux(int current, std::vector & dfsTowns, bool visited []) const; + + /** + * Road + * Contains index of originating town, whether or not is bridge, + * and length + */ + class Road + { + public: + + /* + * Constructor + * @param head Index in vertex array of originating town + * @param isBridge Whether or not the road is a bridge + * @param length Length of the road in miles + */ + Road(int head, int tail, char isBridge, double length) + : _head(head), _tail(tail), _isBridge(isBridge), _length(length) + {} + + int _head; // Index of originating town in vertex array + int _tail; + char _isBridge; + double _length; + + bool operator < (Road road2) const; +}; + +/** +* Town +* Contains name and a list of roads that connect to it +*/ +class Town +{ +public: // consider making some of these private (RoadList) + std::string _name; + typedef std::list RoadList; + RoadList _roads; +}; + + int _numberOfTowns; + int _numberOfRoads; + Town *_towns; + std::vector _roads; };