Advertisement
adityasuman100

Min Cost Path

Mar 6th, 2025
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.09 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <stack>
  5. #include <set>
  6. using namespace std;
  7.  
  8. // Direction flags (using bits to allow multiple directions)
  9. enum Direction {
  10.     NONE = 0,
  11.     DIAGONAL = 1,  // 001
  12.     UP = 2,        // 010
  13.     LEFT = 4       // 100
  14. };
  15.  
  16. // Position in the grid
  17. struct Position {
  18.     int row;
  19.     int col;
  20.    
  21.     Position(int r, int c) : row(r), col(c) {}
  22.    
  23.     // Needed for storing positions in a vector path
  24.     bool operator==(const Position& other) const {
  25.         return row == other.row && col == other.col;
  26.     }
  27. };
  28.  
  29. // Path representation
  30. typedef vector<Position> Path;
  31.  
  32. // Function to find all minimum cost paths from (0,0) to (m,n)
  33. int findAllMinCostPaths(vector<vector<int>>& cost, int m, int n, vector<Path>& allPaths) {
  34.     // Create dp table for minimum costs
  35.     vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
  36.    
  37.     // Create a table to track all directions that lead to minimum cost
  38.     // We use bit flags to represent multiple directions
  39.     vector<vector<int>> dirs(m + 1, vector<int>(n + 1, NONE));
  40.    
  41.     // Base case: cost to reach (0,0) is the cost of the cell itself
  42.     dp[0][0] = cost[0][0];
  43.    
  44.     // Fill the first column (can only come from above)
  45.     for (int i = 1; i <= m; i++) {
  46.         dp[i][0] = dp[i-1][0] + cost[i][0];
  47.         dirs[i][0] = UP;
  48.     }
  49.    
  50.     // Fill the first row (can only come from left)
  51.     for (int j = 1; j <= n; j++) {
  52.         dp[0][j] = dp[0][j-1] + cost[0][j];
  53.         dirs[0][j] = LEFT;
  54.     }
  55.    
  56.     // Fill the rest of the dp table
  57.     for (int i = 1; i <= m; i++) {
  58.         for (int j = 1; j <= n; j++) {
  59.             // Get costs from all three directions
  60.             int fromAbove = dp[i-1][j];
  61.             int fromLeft = dp[i][j-1];
  62.             int fromDiagonal = dp[i-1][j-1];
  63.            
  64.             // Find the minimum cost among all directions
  65.             int minCost = min({fromAbove, fromLeft, fromDiagonal});
  66.            
  67.             // Set the cost for current cell
  68.             dp[i][j] = cost[i][j] + minCost;
  69.            
  70.             // Track all directions that lead to the minimum cost
  71.             if (fromDiagonal == minCost) {
  72.                 dirs[i][j] |= DIAGONAL;  // Set the DIAGONAL bit
  73.             }
  74.             if (fromAbove == minCost) {
  75.                 dirs[i][j] |= UP;  // Set the UP bit
  76.             }
  77.             if (fromLeft == minCost) {
  78.                 dirs[i][j] |= LEFT;  // Set the LEFT bit
  79.             }
  80.         }
  81.     }
  82.    
  83.     // Clear the paths vector
  84.     allPaths.clear();
  85.    
  86.     // Define a recursive function to find all paths
  87.     function<void(int, int, Path&)> findPaths = [&](int i, int j, Path& currentPath) {
  88.         // Add current position to path
  89.         currentPath.push_back(Position(i, j));
  90.        
  91.         // If we've reached the origin, we've found a complete path
  92.         if (i == 0 && j == 0) {
  93.             // Reverse path and add to results
  94.             Path completePath = currentPath;
  95.             reverse(completePath.begin(), completePath.end());
  96.             allPaths.push_back(completePath);
  97.         } else {
  98.             // Try all possible directions from current cell
  99.             if (dirs[i][j] & DIAGONAL) {
  100.                 findPaths(i-1, j-1, currentPath);
  101.             }
  102.             if (dirs[i][j] & UP) {
  103.                 findPaths(i-1, j, currentPath);
  104.             }
  105.             if (dirs[i][j] & LEFT) {
  106.                 findPaths(i, j-1, currentPath);
  107.             }
  108.         }
  109.        
  110.         // Backtrack by removing current position
  111.         currentPath.pop_back();
  112.     };
  113.    
  114.     // Start the recursive search from the destination
  115.     Path currentPath;
  116.     findPaths(m, n, currentPath);
  117.    
  118.     // Return the minimum cost
  119.     return dp[m][n];
  120. }
  121.  
  122. // Function to print a single path with costs
  123. void printPath(const Path& path, const vector<vector<int>>& cost) {
  124.     int runningSum = 0;
  125.     for (const auto& pos : path) {
  126.         runningSum += cost[pos.row][pos.col];
  127.         cout << "(" << pos.row << "," << pos.col << ") -> Cost: " << cost[pos.row][pos.col]
  128.              << " (Running total: " << runningSum << ")" << endl;
  129.     }
  130. }
  131.  
  132. int main() {
  133.     // Example cost matrix with multiple equal-cost paths
  134.     vector<vector<int>> cost = {
  135.         {1, 3, 1},
  136.         {2, 2, 2},
  137.         {4, 1, 1}
  138.     };
  139.    
  140.     // Get dimensions of the matrix (0-indexed)
  141.     int m = cost.size() - 1;
  142.     int n = cost[0].size() - 1;
  143.    
  144.     // Vector to store all minimum cost paths
  145.     vector<Path> allPaths;
  146.    
  147.     // Calculate minimum cost and get all paths
  148.     int minCost = findAllMinCostPaths(cost, m, n, allPaths);
  149.    
  150.     // Print the minimum cost
  151.     cout << "Minimum cost to reach (" << m << "," << n << ") from (0,0): " << minCost << endl;
  152.    
  153.     // Print all minimum cost paths
  154.     cout << "Found " << allPaths.size() << " minimum cost path(s):" << endl;
  155.     for (int i = 0; i < allPaths.size(); i++) {
  156.         cout << "Path " << (i + 1) << ":" << endl;
  157.         printPath(allPaths[i], cost);
  158.         cout << endl;
  159.     }
  160.    
  161.     return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement