Project Euler #83: Path sum: four ways

Sort by

recency

|

14 Discussions

|

  • + 0 comments

    This is perfect python code using dijkstra algorithm.

    import heapq
    
    def matrix_to_weighted_graph(matrix):
        rows, cols = len(matrix), len(matrix[0])
        graph = {}
        
        for i in range(rows):
            for j in range(cols):
                node = (i, j)  # Each element is a node
                neighbors = {}
                
                # Check and add valid neighbors with weights (value of neighboring element)
                if i > 0:  # Up
                    neighbors[(i-1, j)] = matrix[i-1][j]
                if i < rows - 1:  # Down
                    neighbors[(i+1, j)] = matrix[i+1][j]
                if j > 0:  # Left
                    neighbors[(i, j-1)] = matrix[i][j-1]
                if j < cols - 1:  # Right
                    neighbors[(i, j+1)] = matrix[i][j+1]
                
                graph[node] = neighbors
        graph[(cols-1, rows-1)] = {}
        return graph
        
    
    def dijkstra(graph, source, target):
        # Initialize distances and priority queue
        distances = {vertex: float('infinity') for vertex in graph}
        distances[source] = 0
        priority_queue = [(0, source)]  # (distance, vertex)
        
        while priority_queue:
            current_distance, current_vertex = heapq.heappop(priority_queue)
            
            # Skip if the distance is outdated
            if current_distance > distances[current_vertex]:
                continue
            
            for neighbor, weight in graph[current_vertex].items():
                distance = current_distance + weight
                # If a shorter path is found
                if distance < distances[neighbor]:
                    distances[neighbor] = distance
                    heapq.heappush(priority_queue, (distance, neighbor))
        
        return distances[target]
        
    T = int(input())
    matrix = []
    for i in range(T):
        line = list(map(int, input().split()))
        matrix.append(line)
        
    rows, cols = len(matrix), len(matrix[0])
    
    graph = matrix_to_weighted_graph(matrix)
    length = matrix[0][0] + dijkstra(graph, (0,0), (rows - 1, cols - 1))
    print(length)
    
  • + 0 comments

    C++

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef pair<long long, long long> Cell;
    
    int N;
    
    pair<int, int> dir[4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    vector<vector<long long>> grid;
    
    
    long long Dijkstra()
    {
        priority_queue<Cell, vector<Cell>, greater<Cell>> Q;                    
        
        vector<long long> cost((N * N) + 1, 1e15);
        vector<pair<int, int>> M(N * N + 1);
        
        cost[0] = 0;
        
        long long index = 0;
        
        for(int i=0; i<N; i++)
        {
            for(int j=0; j<N; j++)
            {            
                M[index] = {i, j};
                index++;                        
            }
        }    
        Q.push({grid[0][0], 0});
        
        while(!Q.empty())
        {
            long long cell = Q.top().second;
            long long currCost = Q.top().first;         
         
            if(cell == N * N - 1) return currCost;
            
            Q.pop();
            
            int y = M[cell].first;
            int x = M[cell].second;
    
            for(auto d : dir)
            {
                int next_y = y + d.first;
                int next_x = x + d.second;
                
                if(next_y < 0 || next_x < 0 || next_y >= N || next_x >= N) continue;
                
                long long nextCost = currCost + grid[next_y][next_x];
                long long next_index = (next_y * N) + next_x;
                
                if(nextCost < cost[next_index])
                {
                    cost[next_index] = nextCost;
                    Q.push({nextCost, next_index});
                }
            }
        }
        return cost[N * N - 1];
    }
    
    int main() 
    {
        cin >> N;
        grid.resize(N, vector<long long>(N));    
        
        for(int i=0; i<N; i++)
        {
            for(int j=0; j<N; j++)
            {
                cin >> grid[i][j];
            }
        }
        long long ans = Dijkstra();
    
        cout << ans;
        return 0;
    }
    
  • + 0 comments

    for C++ remove all log fector of searching in map mean's do not use map use 2d array of list of pair, int i got AC using

    long long dist[701][701];
    list<pair<pair<int,int>,int>> graph[701][701];
    

    use stl set c++ as priority queue.

  • + 0 comments

    Can't be solvable by DP but by Dijkstra. My solution:

          #include<bits/stdc++.h>
          #define ull unsigned long long
          using namespace std;
          bool is_valid(ull i,ull j,ull n){
                  if(i<0 || j<0 || i>=n || j>=n) return false;
                  return true;
          }
          int main() {
                  ull n;
                  cin>>n;
                  vector<vector<ull>> a(n, vector<ull>(n, 0));
                  for(ull i=0;i<n;i++) for(ull j=0;j<n;j++) cin>>a[i][j];
                  vector<pair<ull,ull> > adj[n*n+1];
                  for(ull i=0;i<n;i++){
                          for(ull j=0;j<n;j++){
                                  if(is_valid(i,j-1,n))adj[i*n+j+1].push_back({a[i][j-1],i*n+j});
                                  if(is_valid(i,j+1,n))adj[i*n+j+1].push_back({a[i][j+1],i*n+j+2});
                                  if(is_valid(i-1,j,n))adj[i*n+j+1].push_back({a[i-1][j],(i-1)*n+j+1});
                                  if(is_valid(i+1,j,n))adj[i*n+j+1].push_back({a[i+1][j],(i+1)*n+j+1});
                          }
                  }
                  priority_queue<pair<ull,ull>,vector<pair<ull,ull>>,greater<pair<ull,ull>> > pq;
                  pq.push({a[0][0],1});
                  vector<bool> vis(n*n+1,false);
                  vector<ull> dis(n*n+1,LONG_MAX);
                  dis[1]=a[0][0];
                  while(!pq.empty()){
                          pair<ull,ull> x=pq.top();
                          dis[x.second]=x.first;
                          vis[x.second] = true;
                          pq.pop();
                          for( auto j:adj[x.second]){
                                  if(!vis[j.second] && dis[j.second]>x.first+j.first){
                                                  dis[j.second]=dis[x.second]+j.first;
                                                  pq.push({dis[j.second],j.second});
                                          }
                          }
                  }
                  cout<<dis[n*n]<<endl;
                  return 0;
          }
    
  • + 0 comments

    I got TLE for using int instead of long long .

    Anyway learned a lot of tricks trying to solve this problem.