我在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);
顶级排序仍然有效。但是,似乎同一问题的大多数实现都使用前一种方法。这会推广到所有有向图吗?在我的本科学位中,我被告知有向图的邻接表应包含每个节点的输出节点列表。对于邻接列表的表示,输入节点与输出节点的选择是否任意?
答案 0 :(得分:0)
对于只需要回答true
或false
的特定问题,翻转所有边缘都没有关系。这是因为当且仅当它没有循环时,该图才是拓扑可排序的。但是,如果您想要取票的顺序,那么在[[0, 1]]
和[[1, 0]]
的不同结果中看不到。
保存图形的哪种方式取决于您解决问题的方式。在这种情况下,我们需要知道每个节点(路线)的度数,并且每次我们从图中删除一个节点(进行路线)时也要对其进行更新,以便我们知道是否可以删除节点(我们可以当indegree为0时执行此操作。更新时,我们将被删除节点指向的每个节点减去1。如果您采用这种方法(大多数情况下都会这样做),很清楚应该如何保存图形