浅谈拓扑排序

背景:

由于学不明白,因此学的时候写一篇助自己理解or回忆的。。。

拓扑排序:

定义:

  • 拓扑排序(Topological sorting)要解决的是如何给一个 DAG(有向无环图)的所有节点排序。
  • 如果这个图中出现或存在环路,那我们没办法进行拓扑排序。 
  • 如果从 i 到 j 有边,则认为 j 依赖于 i。如果说 i 能到达 j ,则认为 j 间接依赖于 i
  • 所以拓扑排序目标将所有结点排序,使得排在前面的结点不能依赖于后面的结点。

 AOV网和AOE网:

举个例子 :生活中的一项大的工程可以看作是由多个子工程组成,这些子工程之间必定有先后联系,即一些工程必须在其他一些工程完成后才能开始:这就是AOV网所能实现的。再比如我现在要知道工程完成的总时间,那么AOE网就可以实现这个。具体展开可以参考下面的网站。拓扑排序 - OI Wiki (oi-wiki.org)

Kahn算法:

图 G=(V,E) 时间复杂度:O(E+V)

主要就是搞清楚怎么去找起点,怎么删边就可以了,代码如下: 

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:其实可以在每次循环的时候,也就是在 push(i) 的地方每次统计一下入队的结点数,如果发现统计的 num 比总结点数要少,那就证明这是一个有环图,有些题目是这样出的。

应用:

 拓扑排序可以判断图中是否有环,还可以用来判断图是否是一条链。拓扑排序可以用来求 AOE 网中的关键路径,估算工程完成的最短时间。

求字典序最大/最小的拓扑排序:

 将 Kahn 算法中的队列替换成最大堆/最小堆实现的优先队列即可,此时总的时间复杂度为 O(E+VlogV)

完结撒花 

                       不平衡才是人生的常态。                         —— ——博人君

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值