模拟队列
#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; }