1 介绍
本专题用来记录拓扑排序相关的题目。
求拓扑序列算法的关键步骤:
- 把入度为0的结点插入队列q。
- 弹出队头t(将t记录下来),遍历队头t的下一个结点,将其入度减1。操作之后,如果其值为0,则插入队列q。
- 重复进行步骤2,直至队列q为空。
- 弹出的元素组成的序列就是一个拓扑序列。
有向无环图等价于图中存在拓扑序列!
2 训练
题目1:1191家谱树
C++代码如下,
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 110;
int n;
int din[N];
vector<vector<int>> g(N);
int main() {
cin >> n;
for (int i = 1; i <= n; ++i) {
int t;
while (cin >> t, t) {
g[i].emplace_back(t);
din[t]++;
}
}
queue<int> q;
for (int i = 1; i <= n; ++i) {
if (din[i] == 0) {
q.push(i);
}
}
vector<int> res;
while (!q.empty()) {
//队列中存储的是,目前所有入度为0的结点
int a = q.front();
q.pop();
res.emplace_back(a);
for (auto b : g[a]) {
din[b]--;
if (din[b] == 0) {
q.push(b);
}
}
}
for (auto x : res) cout << x << " ";
cout << endl;
return 0;
}
题目2:1192奖金
C++代码如下,
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std