拓扑序

通俗解释拓扑序就是一个包含依赖关系的序列
假设做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;
}
posted @   0x7F  阅读(143)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示