📌  相关文章
📜  最后根据依赖项打印完成的任务

📅  最后修改于: 2021-04-29 09:21:01             🧑  作者: Mango

给定XY形式的N个依存关系,其中X和Y代表两个不同的任务。依赖关系XY表示形式为Y-> X的依赖关系,即,如果任务Y发生,则任务X将发生,换句话说,任务Y必须首先完成才能启动任务X。还给定M个任务将首先启动。任务是按字典顺序打印将在最后完成的所有任务。请注意,这些任务将仅由大写英文字母表示。

方法: DFS可以用来解决问题。形式XY(Y-> X)的依存关系可以表示为图中图中从节点Y到节点X的边。从M个初始节点中的每个初始节点启动DFS,并使用布尔数组将遇到的节点标记为已访问。最后,按字典顺序打印使用DFS覆盖的节点/任务。该方法之所以有效,是因为DFS将以顺序的方式覆盖从初始节点开始的所有节点。

考虑下面的图表,该图表代表了上面的第一个示例:

该图将DFS期间初始任务B和C覆盖的边缘显示为红色。
颜色。这样访问的节点是A,B,C和D。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#include 
#include 
using namespace std;
  
// Graph class represents a directed graph
// using adjacency list representation
class Graph {
  
    // Number of vertices
    int V;
  
    // Pointer to an array containing
    // adjacency lists
    vector* adj;
  
    // Boolean array to mark tasks as visited
    bool visited[26];
  
    // A recursive function used by DFS
    void DFSUtil(int v);
  
public:
    // Constructor
    Graph()
    {
  
        // There are only 26 English
        // upper case letters
        this->V = 26;
        adj = new vector[26];
    }
  
    // Function to add an edge to the graph
    void addEdge(char v, char w);
  
    // DFS traversal of the vertices
    // reachable from v
    void DFS(char start[], int M);
  
    void printTasks();
};
  
// Function to add an edge to the graph
void Graph::addEdge(char v, char w)
{
  
    // Add w to v's list
    adj[v - 65].push_back(w - 65);
}
  
void Graph::DFSUtil(int v)
{
  
    // Mark the current node as visited and
    // print it
    visited[v] = true;
  
    // Recur for all the vertices adjacent
    // to this vertex
    vector::iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); ++i)
        if (!visited[*i])
            DFSUtil(*i);
}
  
// DFS traversal of the vertices reachable
// from start nodes
// It uses recursive DFSUtil()
void Graph::DFS(char start[], int M)
{
    // Mark all the vertices as not visited
    for (int i = 0; i < V; i++)
        visited[i] = false;
  
    // Call the recursive helper function
    // to print DFS traversal
    for (int i = 0; i < M; i++)
        DFSUtil(start[i] - 65);
}
  
// Helper function to print the tasks in
// lexicographical order that are completed
// at the end of the DFS
void Graph::printTasks()
{
    for (int i = 0; i < 26; i++) {
        if (visited[i])
            cout << char(i + 65) << " ";
    }
    cout << endl;
}
  
// Driver code
int main()
{
    // Create the graph
    Graph g;
    g.addEdge('B', 'A');
    g.addEdge('B', 'C');
    g.addEdge('A', 'D');
    g.addEdge('C', 'D');
    g.addEdge('E', 'B');
  
    // Initial tasks to be run
    char start[] = { 'B', 'C' };
    int n = sizeof(start) / sizeof(char);
  
    // Start the dfs
    g.DFS(start, n);
  
    // Print the tasks that will get finished
    g.printTasks();
  
    return 0;
}


Python3
# Python3 implementation of the approach
from collections import defaultdict 
  
# This class represents a directed graph 
# using adjacency list representation 
class Graph: 
  
    # Constructor 
    def __init__(self): 
  
        # Default dictionary to store the graph 
        self.graph = defaultdict(list) 
        self.visited = [False]*26
  
    # Function to add an edge to the graph 
    def addEdge(self, u, v): 
        self.graph[ord(u)-65].append(ord(v)-65) 
  
    # A function used by DFS 
    def DFSUtil(self, v): 
          
        # Mark the current node as visited 
        # and print it 
        self.visited[v]= True
  
        # Recur for all the vertices adjacent 
        # to this vertex 
        for i in self.graph[v]: 
            if self.visited[i] == False: 
                self.DFSUtil(i) 
  
  
    # Function to perform the DFS traversal 
    # It uses recursive DFSUtil() 
    def DFS(self, start, M): 
          
        # Total vertices 
        V = len(self.graph)
          
        # Call the recursive helper function 
        # to print the DFS traversal starting 
        # from all vertices one by one 
        for i in range(M):
            self.DFSUtil(ord(start[i])-65) 
      
    def printOrder(self):
        for i in range(26):
            if self.visited[i] == True:
                print(chr(i + 65), end =" ")
        print("\n")
  
# Driver code 
g = Graph() 
g.addEdge('B', 'A') 
g.addEdge('B', 'C') 
g.addEdge('A', 'D') 
g.addEdge('C', 'D') 
g.addEdge('E', 'B') 
  
g.DFS(['B', 'C'], 2) 
g.printOrder()


输出:
A B C D

时间复杂度: O(V + E),其中V是图形中节点的数量,E是边或依存关系的数量。在这种情况下,由于V始终为26,因此时间复杂度为O(26 + E)或在最坏的情况下仅为O(E)。
空间复杂度: O(V + E)