Shortest Path Visiting All Nodes in C++

C++Server Side ProgrammingProgramming

Suppose we have one undirected, connected graph with N nodes these nodes are labeled as 0, 1, 2, ..., N-1. graph length will be N, and j is not same as i is in the list graph[i] exactly once, if and only if nodes i and j are connected. We have to find the length of the shortest path that visits every node. We can start and stop at any node, we can revisit nodes multiple times, and we can reuse edges.

So, if the input is like [[1],[0,2,4],[1,3,4],[2],[1,2]], then the output will be 4. Now here one possible path is [0,1,4,2,3].

To solve this, we will follow these steps −

  • Define one queue

  • n := size of graph

  • req := 2^(n - 1)

  • Define one map

  • for initialize i := 0, when i < n, update (increase i by 1), do −

    • insert {0 OR (2^i), i} into q

  • if n is same as 1, then −

    • return 0

  • for initialize lvl := 1, when not q is empty, update (increase lvl by 1), do −

    • sz := size of q

    • while sz is non-zero, decrease sz by 1 in each iteration, do −

      • Define an array curr = front element of q

      • delete element from q

      • for initialize i := 0, when i < size of graph[curr[1]], update (increase i by 1), do

        • u := graph[curr[1], i]

        • newMask := (curr[0] OR 2^u)

        • if newMask is same as req, then −

          • return lvl

        • if call count(newMask) of visited[u], then −

          • Ignore following part, skip to the next iteration

        • insert newMask into visited[u]

        • insert {newMask, u} into q

  • return -1

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
   cout << "[";
   for(int i = 0; i<v.size(); i++){
      cout << v[i] << ", ";
   }
   cout << "]"<<endl;
}
class Solution {
   public:
   int shortestPathLength(vector<vector<int> >& graph){
      queue<vector<int> > q;
      int n = graph.size();
      int req = (1 << n) - 1;
      map<int, set<int> > visited;
      for (int i = 0; i < n; i++) {
         q.push({ 0 | (1 << i), i });
      }
      if (n == 1)
      return 0;
      for (int lvl = 1; !q.empty(); lvl++) {
         int sz = q.size();
         while (sz--) {
            vector<int> curr = q.front();
            q.pop();
            for (int i = 0; i < graph[curr[1]].size(); i++) {
               int u = graph[curr[1]][i];
               int newMask = (curr[0] | (1 << u));
               if (newMask == req)
                  return lvl;
               if (visited[u].count(newMask))
               continue;
               visited[u].insert(newMask);
               q.push({ newMask, u });
            }
         }
      }
      return -1;
   }
};
main(){
   Solution ob;
   vector<vector<int>> v = {{1},{0,2,4},{1,3,4},{2},{1,2}};
   cout << (ob.shortestPathLength(v));
}

Input

{{1},{0,2,4},{1,3,4},{2},{1,2}}

Output

4
raja
Published on 04-Jun-2020 08:19:28
Advertisements