通俗解释拓扑序就是一个包含依赖关系的序列 假设做C之前必须做完B,做B之前必须做完A,拓扑序就是ABC
实现思路
维护各个节点的入度,将入度为0的节点入队 将入度为0的节点的所有周边节点的入度减1,并将入度为0的节点入队 当队列为空时,过程结束。 若图中存在环路,则进入队列的元素个数<总节点个数,由此可判断图中是否存在环
易错点
拓扑序只能验证图中是否存在环,而无法对图的连通性做出验证
代码实现
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int head[N], e[N], ne[N], idx;
int in[N], q[N];
void insert(int a, int b)
{
e[idx] = b;
ne[idx] = head[a];
head[a] = idx ++;
}
bool topsort()
{
int hh = 0, tt = -1;
for (int i = 1; i < n; ++ i)
if (!in[i]) q[++ tt] = i;
while (hh <= tt)
{
int t = q[hh ++];
for (int i = head[t]; i != -1; i = ne[i])
{
int c = e[i];
-- in[c];
if (!in[c]) q[++ tt] = c;
}
}
return tt == n - 1; // 如果存在拓扑序列也就是不存在环路,那么所有点一定都可以被访问到,由于tt从0开始,n个点tt最大为n-1
}
int main()
{
memset(head, -1, sizeof head); // 初始化链表头需要在更新链表之前进行
cin >> n >> m;
for (int i = 0; i < m; ++ i)
{
int a, b;
cin >> a >> b;
insert(a, b);
++ in[b];
}
if (!topsort()) cout << -1 << endl;
else
{
// 非常巧妙的是如果存在拓扑序列,那么它正好就是队列中的顺序
for (int i = 0; i < n; ++ i) cout << q[i] << ' ';
cout << endl;
}
return 0;
}
标签:idx,int,拓扑,入度,++,节点
From: https://blog.51cto.com/u_14882565/6841316