B3644 拓扑排序 & 家谱树 - 洛谷

【模板】拓扑排序 / 家谱树

题目描述

有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。给出每个人的后代的信息。输出一个序列,使得每个人的后辈都比那个人后列出。

输入格式

1 行一个整数 N1N100),表示家族的人数。接下来 N 行,第 i 行描述第 i 个人的后代编号 ai,j,表示 ai,ji 的后代。每行最后是 0 表示描述完毕。

输出格式

输出一个序列,使得每个人的后辈都比那个人后列出。如果有多种不同的序列,输出任意一种即可。

样例 #1

样例输入 #1

5
0
4 5 1 0
1 0
5 3 0
3 0

样例输出 #1

2 4 5 3 1

很久之前可能是 Gpt 写的代码
邻接表的写法:

void solve() {
    int n;cin >> n;
    vector<vector<int>> g(n + 1);
    for (int i = 1;i <= n;i++) {
        int x;
        while (cin >> x && x) {
            g[i].push_back(x);
        }
    }
    vector<int> in(n + 1);

    for (int i = 1;i <= n;i++) {
        for (auto j : g[i]) {
            in[j]++;
        }
    }
    queue<int>q;
    for (int i = 1;i <= n;i++) {
        if (!in[i])q.push(i);
    }
    
	vector<int> ans;
    while (q.size()) {
        auto u = q.front();q.pop();
        ans.push_back(u);
        for (auto v : g[u]) {
            if (--in[v] == 0) {
                q.push(v);
            }
        }
    }
    for (auto x : ans)cout << x << " ";
}

../../算法知识/图论/链式前向星存图

#include <bits/stdc++.h>
using namespace std;
struct Edge
{
    int to, next;
} edge[2*N];
int head[N], du[N];
int cnt, n;
void addEdge(int u, int v)
{
    edge[cnt] = {v, head[u]};
    head[u] = cnt++;
}
void topsort()
{
    queue<int> q;
    for (int i = 1; i <= n; i++)
        if (!du[i])
            q.push(i);
    vector<int> result;
    while (!q.empty())
    {
        int person = q.front();
        q.pop();
        result.push_back(person);
        for (int i = head[person]; i != -1; i = edge[i].next)
        {
            int son = edge[i].to;
            du[son]--;
            if (!du[son])
                q.push(son);
        }
    }
    for (int i = 0; i < result.size(); i++)
        cout << result[i] << " ";
}
int main()
{
    cin >> n;
    memset(head, -1, sizeof head);// memset(du, 0, sizeof du);
    for (int i = 1; i <= n; i++)
    {
        int x;
        while (cin >> x && x != 0)
            addEdge(i, x), du[x]++;
    }
    topsort();
}