📜  从其他每个节点到达节点0的最小反转次数

📅  最后修改于: 2021-04-26 18:04:53             🧑  作者: Mango

给定一个有N个顶点的值从0到N – 1N – 1边的有向图,任务是计算必须颠倒的边数,以便始终存在从每个节点到节点0的路径。

例子:

方法:想法是对图形使用BFS遍历。步骤如下:

  1. 创建一个有向图,使给定图的边缘方向相反。
  2. 创建一个队列并将节点0推送到队列中。
  3. 在图表上进行BFS遍历期间,请执行以下操作:
    • 从队列中弹出最前面的节点(例如current_node)。
    • 在反向图中遍历当前节点的邻接列表,并将未访问的那些节点压入队列。
    • 在反向图中遍历当前节点的邻接列表,并将未访问的那些节点压入队列。
    • 在上述步骤中插入到队列中的总节点数是需要反转的边数,因为连接到当前节点并且在图中尚未访问的节点无法到达节点0 ,因此,我们需要扭转他们的方向。将以上步骤中的节点数添加到最终数中。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find minimum reversals
int minRev(vector > edges,
           int n)
{
 
    // Add all adjacent nodes to
    // the node in the graph
    unordered_map > graph;
    unordered_map > graph_rev;
 
    for (int i = 0;
         i < edges.size(); i++) {
 
        int x = edges[i][0];
        int y = edges[i][1];
 
        // Insert edges in the graph
        graph[x].push_back(y);
 
        // Insert edges in the
        // reversed graph
        graph_rev[y].push_back(x);
    }
 
    queue q;
 
    // Create array visited to mark
    // all the visited nodes
    vector visited(n, 0);
    q.push(0);
 
    // Stores the number of
    // edges to be reversed
    int ans = 0;
 
    // BFS Traversal
    while (!q.empty()) {
 
        // Pop the current node
        // from the queue
        int curr = q.front();
 
        // mark the current
        // node visited
        visited[curr] = 1;
 
        // Intitialize count of edges
        // need to be reversed to 0
        int count = 0;
        q.pop();
 
        // Push adjacent nodes in the
        // reversed graph to the queue,
        // if not visited
        for (int i = 0;
             i < graph_rev[curr].size();
             i++) {
 
            if (!visited[graph_rev[curr][i]]) {
                q.push(graph_rev[curr][i]);
            }
        }
 
        // Push adjacent nodes in graph
        // to the queue, if not visited
        // count the number of
        // nodes added to the queue
        for (int i = 0;
             i < graph[curr].size();
             i++) {
 
            if (!visited[graph[curr][i]]) {
                q.push(graph[curr][i]);
                count++;
            }
        }
 
        // Update the reverse edge
        // to the final count
        ans += count;
    }
 
    // Return the result
    return ans;
}
 
// Driver Code
int main()
{
    vector > edges;
 
    // Given edges to the graph
    edges = { { 0, 1 }, { 1, 3 }, { 2, 3 },
              { 4, 0 }, { 4, 5 } };
 
    // Number of nodes
    int n = 6;
 
    // Function Call
    cout << minRev(edges, n);
    return 0;
}


Python3
# Python3 program for the above approach
  
# Function to find minimum reversals
def minRev(edges, n):
  
    # Add all adjacent nodes to
    # the node in the graph
    graph = dict()
    graph_rev = dict()
     
    for i in range(len(edges)):
  
        x = edges[i][0];
        y = edges[i][1];
  
        # Insert edges in the graph
        if x not in graph:
            graph[x] = []
        graph[x].append(y);
  
        # Insert edges in the
        # reversed graph
        if y not in graph_rev:
            graph_rev[y] = []
        graph_rev[y].append(x);
     
    q = []
  
    # Create array visited to mark
    # all the visited nodes
    visited = [0 for i in range(n)]
    q.append(0);
  
    # Stores the number of
    # edges to be reversed
    ans = 0;
  
    # BFS Traversal
    while (len(q) != 0):
  
        # Pop the current node
        # from the queue
        curr = q[0]
  
        # mark the current
        # node visited
        visited[curr] = 1;
  
        # Intitialize count of edges
        # need to be reversed to 0
        count = 0;
        q.pop(0);
  
        # Push adjacent nodes in the
        # reversed graph to the queue,
        # if not visited
        if curr in graph_rev:
            for i in range(len(graph_rev[curr])):
  
                if (not visited[graph_rev[curr][i]]):
                    q.append(graph_rev[curr][i]);
  
        # Push adjacent nodes in graph
        # to the queue, if not visited
        # count the number of
        # nodes added to the queue
        if curr in graph:
            for i in range(len(graph[curr])):
  
                if (not visited[graph[curr][i]]):
                    q.append(graph[curr][i]);
                    count += 1
  
        # Update the reverse edge
        # to the final count
        ans += count;
     
    # Return the result
    return ans;
  
# Driver Code
if __name__=='__main__':
 
    edges = []
  
    # Given edges to the graph
    edges = [ [ 0, 1 ], [ 1, 3 ], [ 2, 3 ],[ 4, 0 ], [ 4, 5 ] ];
  
    # Number of nodes
    n = 6;
  
    # Function Call
    print(minRev(edges, n))
     
# This code is contributed by rutvik_56


C#
// C# program for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG{
     
// Function to find minimum reversals
static int minRev(ArrayList edges, int n)
{
     
    // Add all adjacent nodes to
    // the node in the graph
    Dictionary graph = new Dictionary();
     
    Dictionary graph_rev = new Dictionary();
     
    for(int i = 0;i < edges.Count; i++)
    {
         
        int x = (int)((ArrayList)edges[i])[0];
        int y = (int)((ArrayList)edges[i])[1];
  
        // Insert edges in the graph
        if (!graph.ContainsKey(x))
        {
            graph[x] = new ArrayList();
        }
        graph[x].Add(y);
  
        // Insert edges in the
        // reversed graph
        if (!graph_rev.ContainsKey(y))
        {
            graph_rev[y] = new ArrayList();
        }
        graph_rev[y].Add(x);
    }
  
    Queue q = new Queue();
  
    // Create array visited to mark
    // all the visited nodes
    ArrayList visited = new ArrayList();
    for(int i = 0; i < n + 1; i++)
    {
        visited.Add(false);
    }
    q.Enqueue(0);
  
    // Stores the number of
    // edges to be reversed
    int ans = 0;
  
    // BFS Traversal
    while (q.Count != 0)
    {
         
        // Pop the current node
        // from the queue
        int curr = (int)q.Peek();
  
        // mark the current
        // node visited
        visited[curr] = true;
  
        // Intitialize count of edges
        // need to be reversed to 0
        int count = 0;
        q.Dequeue();
  
        // Enqueue adjacent nodes in the
        // reversed graph to the queue,
        // if not visited
        if (graph_rev.ContainsKey(curr))
        {
            for (int i = 0;
                     i < graph_rev[curr].Count;
                     i++)
            {
                if (!(bool)visited[(int)(
                    (ArrayList)graph_rev[curr])[i]])
                {
                    q.Enqueue((int)(
                        (ArrayList)graph_rev[curr])[i]);
                }
            }
        }
  
        // Enqueue adjacent nodes in graph
        // to the queue, if not visited
        // count the number of
        // nodes added to the queue
        if (graph.ContainsKey(curr))
        {
            for(int i = 0;
                    i < ((ArrayList)graph[curr]).Count;
                    i++)
            {
                if (!(bool)visited[(int)(
                    (ArrayList)graph[curr])[i]])
                {
                    q.Enqueue((int)(
                        (ArrayList)graph[curr])[i]);
                    count++;
                }
            }
        }
  
        // Update the reverse edge
        // to the final count
        ans += count;
    }
  
    // Return the result
    return ans;
}
  
// Driver Code
public static void Main(string []args)
{
    ArrayList edges = new ArrayList(){
                      new ArrayList(){ 0, 1 },
                      new ArrayList(){ 1, 3 },
                      new ArrayList(){ 2, 3 },
                      new ArrayList(){ 4, 0 },
                      new ArrayList(){ 4, 5 } };
  
    // Number of nodes
    int n = 6;
     
    // Function Call
    Console.Write(minRev(edges, n));
}
}
 
// This code is contributed by pratham76


输出:
3

时间复杂度: O(V + E) ,其中V是顶点数,E是边数。
辅助空间: O(V) ,其中V是顶点数。