拓扑排序中的邻接列表表示

时间:2019-03-04 00:46:52

标签: c++ algorithm data-structures graph-theory topological-sort

我在Leetcode https://leetcode.com/problems/course-schedule/discuss/58509/18-22-lines-C++-BFSDFS-Solutions上使用DFS看到了以下拓扑排序的实现

现在让我感到困惑的部分是用于有顶图的有向图的表示。该图创建如下:

vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {
    vector<unordered_set<int>> graph(numCourses);
    for (auto pre : prerequisites)
        graph[pre.second].insert(pre.first);
    return graph;
}

这行使我感到困惑:

    graph[pre.second].insert(pre.first);

大概该图被表示为邻接表;如果是这样,为什么每个节点都由传入边缘而不是传出边缘表示?有趣的是,如果我像这样翻转pre.second和pre.first:

graph[pre.first].insert(pre.second);

顶级排序仍然有效。但是,似乎同一问题的大多数实现都使用前一种方法。这会推广到所有有向图吗?在我的本科学位中,我被告知有向图的邻接表应包含每个节点的输出节点列表。对于邻接列表的表示,输入节点与输出节点的选择是否任意?

1 个答案:

答案 0 :(得分:0)

对于只需要回答truefalse的特定问题,翻转所有边缘都没有关系。这是因为当且仅当它没有循环时,该图才是拓扑可排序的。但是,如果您想要取票的顺序,那么在[[0, 1]][[1, 0]]的不同结果中看不到。

保存图形的哪种方式取决于您解决问题的方式。在这种情况下,我们需要知道每个节点(路线)的度数,并且每次我们从图中删除一个节点(进行路线)时也要对其进行更新,以便我们知道是否可以删除节点(我们可以当indegree为0时执行此操作。更新时,我们将被删除节点指向的每个节点减去1。如果您采用这种方法(大多数情况下都会这样做),很清楚应该如何保存图形