访问给定图的所有节点的最小顶点集
给定一个有 N 个节点的有向无环图,任务是找到可以访问完整图的最小顶点集。
例子:
Input: Graph in the image below
Output: 0 4
Explanation: From vertex 0, the set of nodes that can be visited is {0 ,1}. Similarly, from vertex 4, {4, 3, 2} can be visited. Hence, the complete graph can be visited from the set {0, 4} which is of the minimum possible size.
Input: Graph in the image below
Output: 3 4
方法 1:给定问题可以使用拓扑排序来解决,以获得顶点的排序,使得对于从U到V的每条有向边, U都在V之前。以下是要遵循的步骤:
- 使用 Khan 算法按拓扑顺序对给定的顶点数组进行排序。
- 维护一个访问过的数组,该数组跟踪访问过的顶点。
- 迭代排序后的数组执行以下操作:
- 如果当前顶点未被访问,则将其插入所需的集合中。
- 使用 DFS 遍历访问从插入节点可到达的所有节点。
下面是上述方法的实现:
Python3
# Python program of the above approach
from collections import defaultdict, deque
class Solution:
# Function to perform DFS
def dfs(self, node, vis, graph):
# add node to visited set
vis.add(node)
for adj in graph[node]:
if (adj not in vis):
self.dfs(adj, vis, graph)
def solve(self, edges):
graph = defaultdict(list)
# dictionary storing
# indegrees of node
indeg = defaultdict(int)
# array to store topological
# sorting of the array
topo_sort = []
vis = set()
for (u, v) in edges:
graph[u].append(v)
# count indegree of each node
indeg[v] += 1
qu = deque()
for u in graph:
# add to ququ ,if indegree
# of node u is 0
if(indeg[u] == 0):
qu.append(u)
# Run till queue is not empty
while(qu):
node = qu.popleft()
# add node to topo_sort
topo_sort.append(node)
# traverse adj nodes
for adj in graph[node]:
# decrement count of indegree
# of each adj node by 1
indeg[adj] -= 1
# if count becomes 0, then
# add adj to qu
if (indeg[adj] == 0):
qu.append(adj)
vis = set()
ans = []
# Take each node from topo_sort
for node in topo_sort:
# check if node is visited
if (node not in vis):
vis.add(node)
ans.append(node)
# Mark all the reachable
# nodes as visited
self.dfs(node, vis, graph)
# finally return ans
return (ans)
obj = Solution()
edges = [[0, 1], [2, 1], [3, 2], [4, 3]]
ans = obj.solve(edges)
print(" ".join(str(n) for n in ans))
C++
// C++ program of the above approach
#include
using namespace std;
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
vector solve(vector>& edges)
{
map graph;
// Dictionary storing
// indgree of nodes
map indeg;
for(auto dt : edges)
{
graph[dt[0]] = dt[1];
// Count indegree of
// each node
indeg[dt[1]] += 1;
}
vector ans;
for(auto it = graph.begin();
it != graph.end(); ++it)
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.count(it->first))
ans.push_back(it->first);
}
// Return Ans
return ans;
}
// Driver code
int main()
{
vector> edges = { { 0, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 } };
vector ans = solve(edges);
for(auto dt : ans)
cout << dt << " ";
return 0;
}
// This code is contributed by rakeshsahni
Java
// Java program of the above approach
import java.util.*;
class GFG{
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
static Vector solve(int[][] edges)
{
HashMap graph = new HashMap();
// Dictionary storing
// indgree of nodes
HashMap indeg = new HashMap();
for(int dt[] : edges)
{
graph.put(dt[0], dt[1]);
// Count indegree of
// each node
if(indeg.containsKey(dt[1])) {
indeg.put(dt[1], indeg.get(dt[1])+1);
}
else
indeg.put(dt[1], 1);
}
Vector ans = new Vector();
for (Map.Entry it : graph.entrySet())
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.containsKey(it.getKey()))
ans.add(it.getKey());
}
// Return Ans
return ans;
}
// Driver code
public static void main(String[] args)
{
int[][]edges = { { 0, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 } };
Vector ans = solve(edges);
for(int dt : ans)
System.out.print(dt+ " ");
}
}
// This code is contributed by shikhasingrajput
Python3
# Python program of the above approach
from collections import defaultdict
class Solution:
# Function to find smallest set
# of vertices from which the
# complete graph can be visited
def solve(self , edges):
graph = defaultdict(list)
# dictionary storing
# indgree of nodes
indeg = defaultdict(int)
for (u,v) in edges:
graph[u].append(v)
# count indegree of
# each node
indeg[v] +=1
ans = []
for u in graph:
# add to ans, if indegree
# of node u is 0
if(indeg[u] == 0):
ans.append(u)
# Return Ans
return (ans)
obj = Solution()
edges = [[0,1] , [2,1] , [3,2] , [4,3] ]
ans= obj.solve(edges)
print(" ".join(str(n) for n in ans))
C#
// C# program of the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
static List solve(int[, ] edges)
{
Dictionary graph
= new Dictionary();
// Dictionary storing
// indgree of nodes
Dictionary indeg
= new Dictionary();
for (int k = 0; k < edges.GetLength(0); k++) {
int keys = edges[k, 0];
int values = edges[k, 1];
graph.Add(keys, values);
// Count indegree of
// each node
if (indeg.ContainsKey(values)) {
indeg[values] += 1;
}
else
indeg.Add(values, 1);
}
List ans = new List();
foreach(KeyValuePair it in graph)
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.ContainsKey(it.Key))
ans.Add(it.Key);
}
// Return Ans
return ans;
}
public static int[] GetRow(int[, ] matrix, int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new int[rowLength];
for (var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
// Driver code
public static void Main(String[] args)
{
int[, ] edges
= { { 0, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 } };
List ans = solve(edges);
foreach(int dt in ans) Console.Write(dt + " ");
}
}
// This code is contributed by 29AjayKumar
输出
0 4
时间复杂度: O(N)
辅助空间: O(N)
方法2:给定问题也可以通过观察度数为0的顶点是任何其他顶点都无法到达的顶点来解决。因此,我们的想法是找到每个顶点的入度,并将入度为0的顶点插入所需的集合中,因为最终可以访问所有其他顶点。
下面是上述方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
vector solve(vector>& edges)
{
map graph;
// Dictionary storing
// indgree of nodes
map indeg;
for(auto dt : edges)
{
graph[dt[0]] = dt[1];
// Count indegree of
// each node
indeg[dt[1]] += 1;
}
vector ans;
for(auto it = graph.begin();
it != graph.end(); ++it)
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.count(it->first))
ans.push_back(it->first);
}
// Return Ans
return ans;
}
// Driver code
int main()
{
vector> edges = { { 0, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 } };
vector ans = solve(edges);
for(auto dt : ans)
cout << dt << " ";
return 0;
}
// This code is contributed by rakeshsahni
Java
// Java program of the above approach
import java.util.*;
class GFG{
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
static Vector solve(int[][] edges)
{
HashMap graph = new HashMap();
// Dictionary storing
// indgree of nodes
HashMap indeg = new HashMap();
for(int dt[] : edges)
{
graph.put(dt[0], dt[1]);
// Count indegree of
// each node
if(indeg.containsKey(dt[1])) {
indeg.put(dt[1], indeg.get(dt[1])+1);
}
else
indeg.put(dt[1], 1);
}
Vector ans = new Vector();
for (Map.Entry it : graph.entrySet())
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.containsKey(it.getKey()))
ans.add(it.getKey());
}
// Return Ans
return ans;
}
// Driver code
public static void main(String[] args)
{
int[][]edges = { { 0, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 } };
Vector ans = solve(edges);
for(int dt : ans)
System.out.print(dt+ " ");
}
}
// This code is contributed by shikhasingrajput
Python3
# Python program of the above approach
from collections import defaultdict
class Solution:
# Function to find smallest set
# of vertices from which the
# complete graph can be visited
def solve(self , edges):
graph = defaultdict(list)
# dictionary storing
# indgree of nodes
indeg = defaultdict(int)
for (u,v) in edges:
graph[u].append(v)
# count indegree of
# each node
indeg[v] +=1
ans = []
for u in graph:
# add to ans, if indegree
# of node u is 0
if(indeg[u] == 0):
ans.append(u)
# Return Ans
return (ans)
obj = Solution()
edges = [[0,1] , [2,1] , [3,2] , [4,3] ]
ans= obj.solve(edges)
print(" ".join(str(n) for n in ans))
C#
// C# program of the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
static List solve(int[, ] edges)
{
Dictionary graph
= new Dictionary();
// Dictionary storing
// indgree of nodes
Dictionary indeg
= new Dictionary();
for (int k = 0; k < edges.GetLength(0); k++) {
int keys = edges[k, 0];
int values = edges[k, 1];
graph.Add(keys, values);
// Count indegree of
// each node
if (indeg.ContainsKey(values)) {
indeg[values] += 1;
}
else
indeg.Add(values, 1);
}
List ans = new List();
foreach(KeyValuePair it in graph)
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.ContainsKey(it.Key))
ans.Add(it.Key);
}
// Return Ans
return ans;
}
public static int[] GetRow(int[, ] matrix, int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new int[rowLength];
for (var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
// Driver code
public static void Main(String[] args)
{
int[, ] edges
= { { 0, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 } };
List ans = solve(edges);
foreach(int dt in ans) Console.Write(dt + " ");
}
}
// This code is contributed by 29AjayKumar
输出
0 4
时间复杂度: O(N)
辅助空间: O(N)