拓扑排序
用来解决循环依赖相关问题!!!
一个有向无环图一定存在一个拓扑序列!一定存在至少一个入度为0的点
有向无环图也被称作拓扑图
先把入度为0的点压入队列,然后进行广度优先搜索(找到队头,弹出队头,对队头能够访问的边进行广搜),并且把对应的边剪掉(入度-1),再进行一次入度为0 的点搜索(判断该点是否入度为0)
再次压入队列。这样的一次维护队列的过程,就完成了拓扑序的维护。每次弹出队头,要把队头进行存储。
848. 有向图的拓扑序列 - AcWing题库
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int in[N];
int main()
{
cin >> n >> m;
vector<vector<int>> g(n + 1);
while(m--){
int x, y;
cin >> x >> y;
g[x].push_back(y); // 建图
in[y]++; // 统计入度
}
queue<int> q;
for(int i = 1; i <= n; i++) {
if(in[i] == 0) q.push(i); // 把入度为0的点入队
}
vector<int> res;
while(q.size()){
int nq = q.size();
for(int i = 0; i < nq; i++){
auto t = q.front();
q.pop();
res.push_back(t); // 把队头放入答案
for(auto x:g[t]){
in[x]--; // 邻边入度减一
if(in[x] == 0) q.push(x); // 如果此时入度为0,则入队
}
}
}
if(res.size() != n) puts("-1");
else{
for(auto x:res) cout << x << ' ';
}
return 0;
}