📜  查找图形的所有母顶点

📅  最后修改于: 2021-10-25 03:29:08             🧑  作者: Mango

母顶点:图 G = (V, E) 中的母顶点是一个顶点 v,使得 G 中的所有其他顶点都可以通过来自 v 的路径到达。 图中可以有零个、一个或多个母顶点一个图表。我们需要找到给定图中的所有母顶点。

例子 :

推荐:在继续解决方案之前,请先在 {IDE} 上尝试您的方法。

天真的方法:
一种简单的方法是在所有顶点上执行 DFS 或 BFS,并确定我们是否可以从该顶点到达所有顶点。
时间复杂度O(V(E+V))

有效的方法:  

  • 使用此算法在给定的图 G 中找到任何母顶点v。
  • 如果存在母顶点,则图 G 中形成强连通分量并包含v的顶点集是该图所有母顶点的集合。

上述想法如何运作?
如果图存在母顶点,则所有母顶点都是包含母顶点的强连通分量的顶点,因为如果v是母顶点并且存在从u -> v的路径,则u必须是母顶点顶点也是如此。

下面是上述方法的实现:

C++
// C++ program to find all the mother vertices
#include 
using namespace std;
 
// This function does DFS traversal
// from given node u, and marks the
// visited nodes in the visited array
void dfs_helper(int u, vector >& adj,
                bool visited[])
{
    if (visited[u])
        return;
 
    visited[u] = true;
 
    for (auto v : adj[u]) {
        if (!visited[v])
            dfs_helper(v, adj, visited);
    }
}
 
// Function that stores the adjacency
// list of the transpose graph of the
// given graph in the trans_adj vector
void getTransposeGraph(vector >& adj,
                       vector >& trans_adj)
{
    for (int u = 0; u < adj.size(); u++) {
        for (auto v : adj[u]) {
            trans_adj[v].push_back(u);
        }
    }
}
 
// Initializes all elements of visited
// array with value false
void initialize_visited(bool visited[], int n)
{
    for (int u = 0; u < n; u++)
        visited[u] = false;
}
 
// Returns the list of mother
// vertices. If the mother vertex
// does not exists returns -1
vector findAllMotherVertices(vector >& adj)
{
    int n = adj.size();
    bool visited[n];
 
    // Find any mother vertex
    // in given graph, G
    initialize_visited(visited, n);
    int last_dfs_called_on = -1;
 
    for (int u = 0; u < n; u++) {
        if (!visited[u]) {
            dfs_helper(u, adj, visited);
            last_dfs_called_on = u;
        }
    }
 
    // Check if we can reach
    // all vertices from
    // last_dfs_called_on node
    initialize_visited(visited, n);
    dfs_helper(last_dfs_called_on, adj, visited);
 
    for (int u = 0; u < n; u++) {
         
        // Check of the mother vertex
        // exist else return -1
        if (!visited[u]) {
            vector emptyVector;
            emptyVector.push_back(-1);
 
            return emptyVector;
        }
    }
 
    // Now in G_transpose, do DFS
    // from that mother vertex,
    // and we will only reach the
    // other mother vertices of G
    int motherVertex = last_dfs_called_on;
 
    // trans_adj is the transpose
    // of the given Graph
    vector > trans_adj(n);
 
    // Function call to get
    // the transpose graph
    getTransposeGraph(adj, trans_adj);
 
    // DFS from that mother vertex
    // in the transpose graph and the
    // visited nodes are all the
    // mother vertices of the given
    // graph G
    initialize_visited(visited, n);
    dfs_helper(motherVertex, trans_adj, visited);
 
    // Vector to store the list
    // of mother vertices
    vector ans;
 
    for (int u = 0; u < n; u++) {
        if (visited[u])
            ans.push_back(u);
    }
 
    // Return the required list
    return ans;
}
 
// Driver Code
int main()
{
    // No. of nodes
    int V = 8;
    vector > adj(V);
 
    adj[0].push_back(1);
    adj[1].push_back(2);
    adj[1].push_back(4);
    adj[1].push_back(5);
    adj[2].push_back(3);
    adj[2].push_back(6);
    adj[3].push_back(2);
    adj[3].push_back(7);
    adj[4].push_back(0);
    adj[4].push_back(5);
    adj[5].push_back(6);
    adj[6].push_back(5);
    adj[6].push_back(7);
 
    // Function call to find the mother vertces
    vector motherVertices = findAllMotherVertices(adj);
 
    // Print answer
    if (motherVertices[0] == -1)
        cout << "No mother vertex exists";
    else {
        cout << "All Mother vertices of the graph are : ";
        for (int v : motherVertices)
            cout << v << " ";
    }
 
    return 0;
}


输出
All Mother vertices of the graph are : 0 1 4 

时间复杂度: O(V+E)
空间复杂度: O(V+E)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。