拓扑排序

前置知识

DAG,是有向图(有向无环图)的简称。

拓扑排序的定义

如果 DAG 的一个遍历序列满足:

  1. 每个点都访问了一遍。
  2. 对于每个便,出发节点在目的地节点的前面输出。

求拓扑排序

定义 $d_i$ 为第 $i$ 个节点的入度

用邻接表储存一个正向建边和反向建边。

如果某个节点的入度为 $0$,那么输出这个节点,并且加入队列。

遍历队列的每个元素,给每个元素的入度减一,并且检查 $d_i$ 是否为 $0$,如果减完后入度为 $0$,那么输出,并加入队列。

重复上面的操作,直到队列为空。

我们会发现拓扑排序已经求出来了。

例题

B3644 【模板】拓扑排序 / 家谱树 – 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

代码

#include <bits/stdc++.h>

using namespace std;
/*
*/
int n;
vector <int> v[100005], v2[100005];
int d[100005];
int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i ++) {
        int x;
        while (cin >> x) {
            if (x == 0) break;
            else v[x].push_back(i), d[x] ++, v2[i].push_back(x);
        }
    } 
    queue <int> q;
    for (int i = 1; i <= n; i ++) {
        if (v[i].size() == 0) {
            cout << i << " ";
            q.push(i);
        }
    }
    // cout << "*\n" << v2[q.front()].size();
    while (q.size()) {
        int x = q.front();
        q.pop();
        for (int i = 0; i < v2[x].size(); i ++) {
            d[v2[x][i]] --;
            // cout << d[v[x][i]] << " ";
            if (d[v2[x][i]] == 0) {
                cout << v2[x][i] << " ";
                q.push(v2[x][i]);
            } 
        }
    }
    return 0;
}
本文链接:https://ztrztr.top/archives/200
版权声明:本文 《拓扑排序》 为 ztrztr 原创。著作权归作者所有。
转载说明:联系作者或者评论区留言获得转载授权,并注明转载地址。

评论

  1. 123123
    Windows Edge 118.0.2088.61
    浙江省宁波市 BGP高防数据中心
    4 月前
    2024-5-24 14:57:32

    good

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇