AcWing 848. 有向图的拓扑序列

模拟队列

#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, m;
int h[N], e[N], ne[N], idx;//邻接表
int d[N];//入度
int q[N];//队列
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
bool topsort() {
    int hh = 0, tt = -1;
    for (int i = 1; i <= n; i ++ )
        if (!d[i])//先把所有入度为0的点插入到队列
            q[ ++ tt] = i;//进入队列
    while (hh <= tt) {
        int t = q[hh ++ ];//取出进度为0
        for (int i = h[t]; i != -1; i = ne[i]) {//所有和i相连的点,也就是和入度为0的点相连的点
            //入度都要减一
            int j = e[i];  //找到出边
            d[j]--;//让入度减,也就是把出边剪掉
            if (d[j] == 0)//当进度减为0,进入队列
                q[ ++ tt] = j;
        }
    }
    return tt == n - 1;//判断是否都入栈
}
int main() {
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);
    for (int i = 0; i < m; i ++ ) {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b);
        d[b] ++ ;
    }
    if (!topsort()) puts("-1");
    else {
        for (int i = 0; i < n; i ++ ) printf("%d ", q[i]);
        puts("");
    }
    return 0;
}

队列

#include <bits/stdc++.h>
using namespace std;
int const N = 1e5 + 10;
int e[N], ne[N], h[N], idx, d[N];
int n, m;
vector<int> ans;
// 建立邻接表
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

// 拓扑排序
void top_sort() {
    queue<int> q;  // 维护一个队列
    for (int i = 1; i <= n; ++i) if (!d[i]) q.push(i);  // 把入度为0的点加入队列
    // 当队列不为空时
    while (q.size()) {
        auto t = q.front();  // 取队头
        q.pop();  // 队头出队
        ans.push_back(t);  // 把这个数字放入答案序列
        for (int i = h[t]; i != -1; i = ne[i]) { // 枚举所有队头元素相邻的元素
            int j = e[i];
            d[j]--;  // 队头元素出队相当于把与队头元素相连的元素的入度减一
            if (!d[j]) q.push(j);  // 把入度为0的元素放入队列
        }
    }
    if (ans.size() == n) { // 输出答案序列
        for (auto a: ans) printf("%d ", a);
    } else cout << "-1";
}

int main() {
    cin >> n >> m;  // 输入点数和边数
    memset(h, -1, sizeof h);  // 初始化h
    for (int i = 0; i < m; ++i) { // 读入每条边
        int a, b;
        scanf("%d %d", &a, &b);
        add(a, b);  // 把b插入a的边表
        d[b]++;  // b的入度加一
    }
    top_sort();
    return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/11831954.html