背景:
由于学不明白,因此学的时候写一篇助自己理解or回忆的。。。
拓扑排序:
定义:
- 拓扑排序(Topological sorting)要解决的是如何给一个 DAG(有向无环图)的所有节点排序。
- 如果这个图中出现或存在环路,那我们没办法进行拓扑排序。
- 如果从
到
有边,则认为
依赖于
。如果说
能到达
,则认为
间接依赖于
。
- 所以拓扑排序目标将所有结点排序,使得排在前面的结点不能依赖于后面的结点。
AOV网和AOE网:
举个例子 :生活中的一项大的工程可以看作是由多个子工程组成,这些子工程之间必定有先后联系,即一些工程必须在其他一些工程完成后才能开始:这就是AOV网所能实现的。再比如我现在要知道工程完成的总时间,那么AOE网就可以实现这个。具体展开可以参考下面的网站。拓扑排序 - OI Wiki (oi-wiki.org)
Kahn算法:
图
时间复杂度:
主要就是搞清楚怎么去找起点,怎么删边就可以了,代码如下:
int n, m;
vector<int> G[MAXN];
int in[MAXN]; // 存储每个结点的入度
bool toposort() {
vector<int> L;
queue<int> S;
for (int i = 1; i <= n; i++)
if (in[i] == 0) S.push(i);
while (!S.empty()) {
int u = S.front();
S.pop();
L.push_back(u);
for (auto v : G[u]) {
if (--in[v] == 0) {
S.push(v);
}
}
}
if (L.size() == n) {
for (auto i : L) cout << i << ' ';
return true;
}
return false;
}
Q:有一个点:那如果你现在不知道图是不是DAG的时候,怎么办?
A:其实可以在每次循环的时候,也就是在 的地方每次统计一下入队的结点数,如果发现统计的
比总结点数要少,那就证明这是一个有环图,有些题目是这样出的。
应用:
拓扑排序可以判断图中是否有环,还可以用来判断图是否是一条链。拓扑排序可以用来求 AOE 网中的关键路径,估算工程完成的最短时间。
求字典序最大/最小的拓扑排序:
将 Kahn 算法中的队列替换成最大堆/最小堆实现的优先队列即可,此时总的时间复杂度为
。
完结撒花
不平衡才是人生的常态。 —— ——博人君