📜  在给定条件下遍历整个矩阵的最小初始顶点

📅  最后修改于: 2021-04-24 20:13:26             🧑  作者: Mango

我们给了一个矩阵,在每个单元格中包含不同的值。我们的目标是找到矩阵中的最小位置集,以便可以从集合中的位置开始遍历整个矩阵。
我们可以在以下条件下遍历矩阵:

  • 我们只能移动到那些值小于或等于当前单元格值的邻居。单元的邻居定义为与给定单元共享一侧的单元。

例子:

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.

从以上示例中,我们可以轻松地识别出,为了使用最少数量的职位,我们必须从具有最高像元值的职位开始。因此,我们选择矩阵中包含最高值的位置。我们将具有最高值的顶点放在单独的数组中。从开始,我们在每个顶点上执行DFS。
最高的价值。如果在dfs中遇到任何未访问的顶点,则必须将此顶点包括在集合中。处理完所有单元后,该集合将包含所需的顶点。

这是如何运作的?
我们需要访问所有顶点并达到最大值,我们必须从它们开始。如果两个最大值不相邻,则必须同时选择两个。如果两个最大值相邻,则可以选择它们中的任何一个,因为允许移动到相等值的邻居。

C++
// C++ program to find minimum initial
// vertices to reach whole matrix.
#include 
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 > > 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;
}


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


输出:
 

0 1