拓扑首先排列最小的可用顶点

时间:2014-11-20 08:31:29

标签: c++ priority-queue depth-first-search topological-sort

我正在尝试解决基于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

我的代码也为其他一些测试用例输出了错误的结果,但我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

问题似乎是在检查当前节点的所有传出边之前调用pq.top

考虑下图:节点:A,B,C;边缘A-> B,A-C。设C具有较小的优先级值,即它应该首先出现。在dfs(A)期间,您在C之前检查B.由于它立即从队列中立即获取,因此首先处理B(但不应该)。因此,在再次查询队列之前插入所有相邻节点。