算法学习笔记:拓扑排序

一、思想
拓扑排序是对DAG(有向无环图)上的节点进行排序,使得对于每一条有向边u->v, u 都在v之前出现。简单地说,是在不破坏节点先后顺序的前提下,把DAG拉成一条链。如果以游戏中的科技树(虽然名字带树,其实常常不是树而只是DAG)举例,拓扑排序就是找到一种可能的点科技树的顺序。

拓扑排序最经典的算法是Kahn算法。
以下是一个 [公式] 的实现( [公式] 分别表示点数和边数),利用了队列:
// deg是入度,在存图的时候需要录入数据
// A是排序后的数组
int deg[MAXN], A[MAXN];
bool toposort(int n)
{
int cnt = 0;
queue q;
for (int i = 1; i <= n; ++i){
if (deg[i] == 0) q.push(i);
}

while (!q.empty()) {
    int t = q.front();
    q.pop();
    A[cnt++] = t;
    for (auto to : edges[t]) {
        deg[to]--;
        if (deg[to] == 0) // 出现了新的入度为0的点
            q.push(to);
    }
}
return cnt == n;

}
返回值为是否成功进行拓扑排序,也即是否存在环。也就是说拓扑排序是可以用来简单地判环的。有时会要求输出字典序最小的方案,这时把queue改成priority_queue即可,复杂度会多一个log 。

你可能感兴趣的:(算法学习笔记:拓扑排序)