图论入门:拓扑排序实战指南

一、上期回顾 Day29

掌握 BFS 广度优先搜索,队列层序遍历,求解迷宫、二叉树层序、无权最短路径。今天进入图论入门,学习图存储与拓扑排序,解决有向图任务依赖问题。

二、图基础概念

  1. 顶点:图中的节点
  2. 边:节点之间的连接关系
  3. 有向图:边有方向,A→B 不等于 B→A
  4. 无向图:边无方向,双向连通
  5. 入度:指向当前节点的边数量
  6. 出度:从当前节点出发的边数量

三、图常用存储:邻接表

刷题首选邻接表,节省空间、遍历高效

复制代码
#include <iostream>
#include <vector>
using namespace std;

const int N = 1005;
vector<int> edge[N];  // 邻接表
int inDegree[N];      // 记录每个点入度

四、拓扑排序核心思想

适用场景:有先后依赖关系的任务排序

  1. 不断选取入度为 0的节点输出
  2. 删除该节点所有出边,相邻节点入度 - 1
  3. 重复操作直到所有节点输出
  4. 最终输出节点数≠总节点数 → 图存在环,无法排序

五、拓扑排序 BFS 标准模板

复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int N = 1005;
vector<int> edge[N];
int inDegree[N];
vector<int> res;

// n个顶点,m条边
bool topoSort(int n, int m)
{
    queue<int> q;
    // 入度为0节点入队
    for(int i = 1; i <= n; i++)
    {
        if(inDegree[i] == 0)
            q.push(i);
    }

    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        res.push_back(u);

        // 遍历所有邻接点
        for(int v : edge[u])
        {
            inDegree[v]--;
            if(inDegree[v] == 0)
                q.push(v);
        }
    }
    // 节点数量相等无环,否则有环
    return res.size() == n;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        edge[a].push_back(b);
        inDegree[b]++;
    }

    bool ok = topoSort(n, m);
    if(ok)
    {
        for(int x : res)
            cout << x << " ";
    }
    else
        cout << "图中存在环路,无法拓扑排序";
    return 0;
}

六、拓扑排序典型场景

  1. 课程先后选修安排
  2. 项目任务依赖执行顺序
  3. 编译文件依赖排序
  4. 判断有向图是否存在环

七、拓扑排序关键点

  1. 依赖关系 A→B:A 先执行,B 后执行
  2. 每次只选无前置依赖(入度 0)节点
  3. 统计最终输出个数,快速判环
  4. 基于 BFS 队列实现,逻辑简单不易出错

八、今日核心总结

  1. 图存储优先使用邻接表
  2. 拓扑排序专门解决有向图依赖排序
  3. 核心:入度清零出队,递减邻接点入度
  4. 输出节点总数判断是否存在环路
  5. 队列 BFS 写法通用性最强

九、课后练习

  1. 搭建简单有向图,运行拓扑排序输出执行顺序
  2. 手动构造带环图,验证判环效果
相关推荐
布莱克60510 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
D e re k ZH12 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
石小石Orz13 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
民乐团扒谱机15 小时前
【微实验】NSGA-II(非支配排序遗传算法)——解决多目标优化问题的“自然选择模拟器”
linux·人工智能·算法
青少儿编程课堂15 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:中缀表达式求值解析
c++·python·算法·bfs·信息学竞赛
武子康17 小时前
Qwen-Drive 到底是什么:4B 级 VLM 如何成为驾驶策略底座
人工智能·算法·机器学习
zh_xuan18 小时前
LeeCode 496. 下一个更大元素I
数据结构·算法·栈·单调栈
机 _ 长19 小时前
05 智算运维|8 张卡怎么才算「捆成一张」:NCCL 实测与拓扑
运维·人工智能·算法·智算运维
早起CaiCai19 小时前
【2023-01 OM】利用深度学习算法融合异质观测实现海洋场降尺度
人工智能·深度学习·算法