#include #include using namespace std; struct Node { Node *left; Node *right; int64_t height; }; void createNewNode(Node &parent, list &freeNodesLeft, list &freeNodesRight, int64_t new_height, bool direction) { // Found a node that will not increase total height. Using Node newNode; newNode.height = new_height; freeNodesLeft.push_back(newNode); freeNodesRight.push_back(newNode); if(!direction) { parent.left = &newNode; } else { parent.right = &newNode; } } int64_t calculateHeight(int64_t N, int64_t leftHeight, int64_t rightHeight) { if (N == 1) { return 0; } int64_t totalHeight = 0; Node parentNode; parentNode.height = 0; list freeNodesLeft; list freeNodesRight; freeNodesLeft.push_back(parentNode); freeNodesRight.push_back(parentNode); int64_t longestRoad = max(leftHeight, rightHeight); // Calculate all houses after first one for (int64_t i = 1; i < N; i++) { Node lowestNodeLeft; lowestNodeLeft.height = longestRoad * N; auto lowestNodeLeftIt = freeNodesLeft.end(); bool foundFreeSolution = false; // Find lowest left node. Also check if using any of the existing nodes will not increase total height for (auto it = freeNodesLeft.begin(); it != freeNodesLeft.end(); it++) { Node node = *it; int64_t new_height = node.height + leftHeight; if (new_height <= totalHeight) { // Found a node that will not increase total height. Using it createNewNode(node, freeNodesLeft, freeNodesRight, new_height, 0); freeNodesLeft.erase(it); foundFreeSolution = true; break; } if (new_height < lowestNodeLeft.height) { lowestNodeLeft = node; lowestNodeLeftIt = it; } } if (foundFreeSolution) { continue; } Node lowestNodeRight; lowestNodeRight.height = longestRoad * N; auto lowestNodeRightIt = freeNodesRight.end(); // Find lowest right node. Also check if using any of the existing nodes will not increase total height for (auto it = freeNodesRight.begin(); it != freeNodesRight.end(); it++) { Node node = *it; int64_t new_height = node.height + rightHeight; if (new_height <= totalHeight) { // Found a node that will not increase total height. Using createNewNode(node, freeNodesLeft, freeNodesRight, new_height, 1); freeNodesRight.erase(it); foundFreeSolution = true; break; } if (new_height < lowestNodeRight.height) { lowestNodeRight = node; lowestNodeRightIt = it; } } if (foundFreeSolution) { continue; } int64_t newHeightLeft = lowestNodeLeft.height + leftHeight; int64_t newHeightRight = lowestNodeRight.height + rightHeight; if (newHeightLeft < newHeightRight) { createNewNode(lowestNodeLeft, freeNodesLeft, freeNodesRight, newHeightLeft, 0); freeNodesLeft.erase(lowestNodeLeftIt); totalHeight = newHeightLeft; } else { createNewNode(lowestNodeRight, freeNodesLeft, freeNodesRight, newHeightRight, 1); freeNodesRight.erase(lowestNodeRightIt); totalHeight = newHeightRight; } //cout << "i=" << i << "; total_height=" << totalHeight << endl; } return totalHeight; } int main() { int64_t T; cin >> T; int64_t N, A, B; for (int i = 0; i < T; i++) { cin >> N >> A >> B; cout << calculateHeight(N, A, B) << endl; } return 0; }