给定一个有N个顶点的值从0到N – 1和N – 1边的有向图,任务是计算必须颠倒的边数,以便始终存在从每个节点到节点0的路径。
例子:
Input: Below is the given graph
Output: 3
Explanation:
Input: Below is the given graph
Output: 0
方法:想法是对图形使用BFS遍历。步骤如下:
- 创建一个有向图,使给定图的边缘方向相反。
- 创建一个队列并将节点0推送到队列中。
- 在图表上进行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是顶点数。