我正在尝试解决基于TopSort的问题。由于将有许多有效的拓扑排序顺序,我需要输出一个按字典顺序排列的最小排序,即首先是最小编号的可用顶点。
我将解释我采用的方法,然后发布代码。我维护了一个数组,其中包含图表每个节点的入边数。还存在邻接矩阵。我有一个布尔数组'visited',它保留了被访问节点的数量,以及一个最小优先级队列,用于在那一刻弹出最小的可用顶点。这是我的代码:
void dfs(int u){
visited[u] = true;
cout<<u<<" ";
list<int>::iterator i;
for(i = adj[u].begin(); i != adj[u].end(); ++i){
if(!visited[*i]){
inedge[*i]--;
if(!inedge[*i]){
pq.push(*i);
}
if(!pq.empty()){
int temp = pq.top();
pq.pop();
dfs(temp);
}
}
}
}
现在,在第一次调用此函数时,优先级队列仅包含inedge [i] = 0(入边数为零)的节点。我从该优先级队列u = pq.top()
中弹出最小节点,然后调用dfs(u)
。
但我的代码输出错误。如果我在这里使用的逻辑错误,有人可以帮助我吗?
我的输入包含N个不完整的序列(每个N中缺少数字)。 输入:
2
1 3
2 3 4
输出:
1 2 3 4
这是正确的预期输出,我的代码确实生成了这个。但是对于this图像中给出的输入 输入:
6
7 8 9
7 11 9
5 11 2
3 8 9
11 10
3 10
预期输出为:
3 5 7 8 11 2 9 10
我的代码输出:
3 5 7 8 11 9 2 10
我的代码也为其他一些测试用例输出了错误的结果,但我不知道如何解决这个问题。
答案 0 :(得分:1)
问题似乎是在检查当前节点的所有传出边之前调用pq.top
。
考虑下图:节点:A,B,C;边缘A-> B,A-C。设C具有较小的优先级值,即它应该首先出现。在dfs(A)期间,您在C之前检查B.由于它立即从队列中立即获取,因此首先处理B(但不应该)。因此,在再次查询队列之前插入所有相邻节点。