We are given a matrix that contains different values in its each cell. Our aim is to find the minimal set of positions in the matrix such that entire matrix can be traversed starting from the positions in the set.

We can traverse the matrix under below conditions:

- We can move only to those neighbors that contain value less than or to equal to the current cell’s value. A neighbor of cell is defined as the cell that shares a side with the given cell.

**Examples: **

Input : 1 2 3 2 3 1 1 1 1 Output : 1 1 0 2 If we start from 1, 1 we can cover 6 vertices in the order (1, 1) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2) -> (1, 2). We cannot cover the entire matrix with this vertex. Remaining vertices can be covered (0, 2) -> (0, 1) -> (0, 0). Input : 3 3 1 1 Output : 0 1 If we start from 0, 1, we can traverse the entire matrix from this single vertex in this order (0, 0) -> (0, 1) -> (1, 1) -> (1, 0). Traversing the matrix in this order satisfies all the conditions stated above.

From the above examples, we can easily identify that in order to use minimum number of positions we have to start from the positions having highest cell value. Therefore we pick the positions that contain the highest value in the matrix. We take the vertices having highest value in separate array. We perform DFS on every vertex starting from the

highest value. If we encounter any unvisited vertex during dfs then we have to include this vertex in our set. When all the cells have been processed then the set contains the required vertices.

**How does this work?**

We need to visit all vertices and to reach largest values we must start with them. If two largest values are not adjacent, then both of them must be picked. If two largest values are adjacent, then any of them can be picked as moving to equal value neighbors is allowed.

## C++

`// C++ program to find minimum initial` `// vertices to reach whole matrix.` `#include <bits/stdc++.h>` `using` `namespace` `std;` `const` `int` `MAX = 100;` `// (n, m) is current source cell from which` `// we need to do DFS. N and M are total no.` `// of rows and columns.` `void` `dfs(` `int` `n, ` `int` `m, ` `bool` `visit[][MAX],` ` ` `int` `adj[][MAX], ` `int` `N, ` `int` `M)` `{` ` ` `// Marking the vertex as visited` ` ` `visit[n][m] = 1;` ` ` `// If below neighbor is valid and has` ` ` `// value less than or equal to current` ` ` `// cell's value` ` ` `if` `(n + 1 < N &&` ` ` `adj[n][m] >= adj[n + 1][m] &&` ` ` `!visit[n + 1][m])` ` ` `dfs(n + 1, m, visit, adj, N, M);` ` ` `// If right neighbor is valid and has` ` ` `// value less than or equal to current` ` ` `// cell's value` ` ` `if` `(m + 1 < M &&` ` ` `adj[n][m] >= adj[n][m + 1] &&` ` ` `!visit[n][m + 1])` ` ` `dfs(n, m + 1, visit, adj, N, M);` ` ` `// If above neighbor is valid and has` ` ` `// value less than or equal to current` ` ` `// cell's value` ` ` `if` `(n - 1 >= 0 &&` ` ` `adj[n][m] >= adj[n - 1][m] &&` ` ` `!visit[n - 1][m])` ` ` `dfs(n - 1, m, visit, adj, N, M);` ` ` `// If left neighbor is valid and has` ` ` `// value less than or equal to current` ` ` `// cell's value` ` ` `if` `(m - 1 >= 0 &&` ` ` `adj[n][m] >= adj[n][m - 1] &&` ` ` `!visit[n][m - 1])` ` ` `dfs(n, m - 1, visit, adj, N, M);` `}` `void` `printMinSources(` `int` `adj[][MAX], ` `int` `N, ` `int` `M)` `{` ` ` `// Storing the cell value and cell indices` ` ` `// in a vector.` ` ` `vector<pair<` `long` `int` `, pair<` `int` `, ` `int` `> > > x;` ` ` `for` `(` `int` `i = 0; i < N; i++)` ` ` `for` `(` `int` `j = 0; j < M; j++)` ` ` `x.push_back(make_pair(adj[i][j],` ` ` `make_pair(i, j)));` ` ` `// Sorting the newly created array according` ` ` `// to cell values` ` ` `sort(x.begin(), x.end());` ` ` `// Create a visited array for DFS and` ` ` `// initialize it as false.` ` ` `bool` `visit[N][MAX];` ` ` `memset` `(visit, ` `false` `, ` `sizeof` `(visit));` ` ` `// Applying dfs for each vertex with` ` ` `// highest value` ` ` `for` `(` `int` `i = x.size()-1; i >=0 ; i--)` ` ` `{` ` ` `// If the given vertex is not visited` ` ` `// then include it in the set` ` ` `if` `(!visit[x[i].second.first][x[i].second.second])` ` ` `{` ` ` `cout << x[i].second.first << ` `" "` ` ` `<< x[i].second.second << endl;` ` ` `dfs(x[i].second.first, x[i].second.second,` ` ` `visit, adj, N, M);` ` ` `}` ` ` `}` `}` `// Driver code` `int` `main()` `{` ` ` `int` `N = 2, M = 2;` ` ` `int` `adj[N][MAX] = {{3, 3},` ` ` `{1, 1}};` ` ` `printMinSources(adj, N, M);` ` ` `return` `0;` `}` |

*chevron_right*

*filter_none*

## Python3

`# Python3 program to find minimum initial` `# vertices to reach whole matrix` `MAX` `=` `100` ` ` `# (n, m) is current source cell from which` `# we need to do DFS. N and M are total no.` `# of rows and columns.` `def` `dfs(n, m, visit, adj, N, M):` ` ` ` ` `# Marking the vertex as visited` ` ` `visit[n][m] ` `=` `1` ` ` ` ` `# If below neighbor is valid and has` ` ` `# value less than or equal to current` ` ` `# cell's value` ` ` `if` `(n ` `+` `1` `< N ` `and` ` ` `adj[n][m] >` `=` `adj[n ` `+` `1` `][m] ` `and` ` ` `not` `visit[n ` `+` `1` `][m]):` ` ` `dfs(n ` `+` `1` `, m, visit, adj, N, M)` ` ` ` ` `# If right neighbor is valid and has` ` ` `# value less than or equal to current` ` ` `# cell's value` ` ` `if` `(m ` `+` `1` `< M ` `and` ` ` `adj[n][m] >` `=` `adj[n][m ` `+` `1` `] ` `and` ` ` `not` `visit[n][m ` `+` `1` `]):` ` ` `dfs(n, m ` `+` `1` `, visit, adj, N, M)` ` ` ` ` `# If above neighbor is valid and has` ` ` `# value less than or equal to current` ` ` `# cell's value` ` ` `if` `(n ` `-` `1` `>` `=` `0` `and` ` ` `adj[n][m] >` `=` `adj[n ` `-` `1` `][m] ` `and` ` ` `not` `visit[n ` `-` `1` `][m]):` ` ` `dfs(n ` `-` `1` `, m, visit, adj, N, M)` ` ` ` ` `# If left neighbor is valid and has` ` ` `# value less than or equal to current` ` ` `# cell's value` ` ` `if` `(m ` `-` `1` `>` `=` `0` `and` ` ` `adj[n][m] >` `=` `adj[n][m ` `-` `1` `] ` `and` ` ` `not` `visit[n][m ` `-` `1` `]):` ` ` `dfs(n, m ` `-` `1` `, visit, adj, N, M)` `def` `printMinSources(adj, N, M):` ` ` `# Storing the cell value and cell ` ` ` `# indices in a vector.` ` ` `x ` `=` `[]` ` ` ` ` `for` `i ` `in` `range` `(N):` ` ` `for` `j ` `in` `range` `(M):` ` ` `x.append([adj[i][j], [i, j]])` ` ` ` ` `# Sorting the newly created array according` ` ` `# to cell values` ` ` `x.sort()` ` ` ` ` `# Create a visited array for DFS and` ` ` `# initialize it as false.` ` ` `visit ` `=` `[[` `False` `for` `i ` `in` `range` `(` `MAX` `)]` ` ` `for` `i ` `in` `range` `(N)]` ` ` ` ` `# Applying dfs for each vertex with` ` ` `# highest value` ` ` `for` `i ` `in` `range` `(` `len` `(x) ` `-` `1` `, ` `-` `1` `, ` `-` `1` `):` ` ` ` ` `# If the given vertex is not visited` ` ` `# then include it in the set` ` ` `if` `(` `not` `visit[x[i][` `1` `][` `0` `]][x[i][` `1` `][` `1` `]]):` ` ` `print` `(` `'{} {}'` `.` `format` `(x[i][` `1` `][` `0` `],` ` ` `x[i][` `1` `][` `1` `]))` ` ` ` ` `dfs(x[i][` `1` `][` `0` `], ` ` ` `x[i][` `1` `][` `1` `],` ` ` `visit, adj, N, M)` ` ` `# Driver code` `if` `__name__` `=` `=` `'__main__'` `:` ` ` `N ` `=` `2` ` ` `M ` `=` `2` ` ` ` ` `adj ` `=` `[ [ ` `3` `, ` `3` `], [ ` `1` `, ` `1` `] ]` ` ` ` ` `printMinSources(adj, N, M)` `# This code is contributed by rutvik_56` |

*chevron_right*

*filter_none*

**Output: **** **

0 1

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Find K vertices in the graph which are connected to at least one of remaining vertices
- Maximize the number of uncolored vertices appearing along the path from root vertex and the colored vertices
- Minimum cost to traverse from one index to another in the String
- Find total no of collisions taking place between the balls in which initial direction of each ball is given
- Nth angle of a Polygon whose initial angle and per angle increment is given
- Count minimum character replacements required such that given string satisfies the given conditions
- Shortest path to traverse all the elements of a circular array in increasing order
- Minimum number of edges between two vertices of a Graph
- Maximum and minimum isolated vertices in a graph
- Minimum Operations to make value of all vertices of the tree Zero
- Minimum number of edges between two vertices of a graph using DFS
- Minimum cost to reduce the integer N to 1 as per given conditions
- Minimum increment/decrement operations required on Array to satisfy given conditions
- Check whether given degrees of vertices represent a Graph or Tree
- Construct a graph from given degrees of all vertices
- Maximize shortest path between given vertices by adding a single edge
- Find two disjoint good sets of vertices in a given graph
- Minimize cost to color all the vertices of an Undirected Graph using given operation
- Change the given string according to the given conditions
- Find if there is a path between two vertices in a directed graph

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.