拓扑排序是对DAG(有向无环图)上的节点进行排序,使得对于每一条有向边 ,
都在
之前出现。简单地说,是在不破坏节点先后顺序的前提下,把DAG拉成一条链。如果以游戏中的科技树(虽然名字带树,其实常常不是树而只是DAG)举例,拓扑排序就是找到一种可能的点科技树的顺序。
Kahn算法
一句话:一直拿走入度为0的点。
O(N+M) n,m分别为点数和边数
// deg是入度,在存图的时候需要录入数据// A是排序后的数组int deg[MAXN], A[MAXN];bool toposort(int n){int cnt = 0;queue<int> 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
