【算法入门&图论】【模板】拓扑排序|【模板】单源最短路2 |最小生成树(上)

简介: 【算法入门&图论】【模板】拓扑排序|【模板】单源最短路2 |最小生成树

🔥前言

本专栏收录的均为牛客网的算法题目,内含链表、双指针、递归、动态规划、基本数据结构等算法思想的具体运用。牛客网不仅有大量的经典算法题目,也有大厂的面试真题,面试、找工作完全可以来这里找机会。此外,网站内的编码主题多样化,调试功能可运用性强,可谓是非常注重用户体验。这么好的免费刷题网站还不快入手吗,快去注册开启算法百炼成神之路吧!


1、AB13 【模板】拓扑排序

学会使用邻接表解决图论问题,巧妙利用vector容器


题目链接:拓朴排序


85f811d96cd44822a84ada34d41a3710.png


1.1、解题思路

解决拓扑排序之前要先认识什么是拓扑排序:


对一个有向无环图(Directed Acyclic Graph简称DAG)图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。


解决步骤:


使用邻接表将顶点联系起来,辅助数组inDegree表示每个顶点的入度。

借助队列和计数器变量来判断该有向图是否有环:

将入度为零的顶点入队(也就是拓扑图第一个顶点)

取队首,遍历与之相邻的顶点,若该顶点入度减一后为零就将其入队

只要队列非空就循环操作,计算器循环加一,与顶点数比较是否相等

本题末尾也不能输出空格,因此输出拓扑序列时要加限制条件

1.2、代码实现与注释

本题源码:

#include<iostream>
#include<vector>
#include<queue>
#define M 200001
using namespace std;
int main() {
    int n, m;
    cin >> n >> m;
    vector<int> adjList[M]; // 模拟邻接表
    int inDegree[M] = { 0 };// 记录每个顶点的入度
    int a, b;
    for (int i = 0; i < m; i++) {
        cin >> a >> b;
        adjList[a].push_back(b);
        inDegree[b]++;
    }
    queue<int> que; // 将初始入度为零的顶点入队
    for (int i = 1; i <= n; i++) {
        if (inDegree[i] == 0)
            que.push(i);
    }
    int cnt = 0; // 用来计数,判断改图是否有环
    vector<int> res; // 用来输出顶点序列
    while (!que.empty()) {
        int u = que.front();
        que.pop();
        res.push_back(u);
        for (int i = 0; i < adjList[u].size(); i++) { // 遍历u的相邻顶点
            int v = adjList[u][i];
            if (--inDegree[v] == 0)
                que.push(v);
        }
        cnt++;
    }
    // 若计数器与顶点数相同则图无环,存在拓扑排序
    if (cnt == n) {
        for (int i = 0; i < res.size(); i++) {
            cout << res[i];
            // 限制输出空格的条件
            if (i != res.size() - 1) {
                cout << " ";
            }
        }
    } else {
        cout << -1;
    }
    return 0;
}

重要注释:


adjList数组是vector类型的,用来模拟邻接表

使用每个元素为一个数组的vector容器模拟邻接表进行建图

vector[a]所对应的数组中存储着该顶点所指向的其他顶点

inDegree数组代表每一个顶点的入度情况

使用一个队列,初始时将所有入度为0的顶点全部入队,之后采用BFS的思想:

依次取出队头元素并存入结果数组中,然后在邻接表中遍历该队头元素所指向的其他顶点

将这些顶点的入度全部减一,若减一后某顶点的入度变为0,则将该顶点进行入队操作,

重复此步骤直至队列为空为止。

设置一个用于判断图中是否存在环(是否可以得到拓扑序列)的计数器,在弹出队头元素后要将计数器加一,最后队列为空后,若计数器的值与顶点数相同,则说明图不存在环,可以得到拓扑序列。


目录
相关文章
|
21天前
|
机器学习/深度学习 安全 算法
【图论】【割点】【C++算法】928. 尽量减少恶意软件的传播 II
【图论】【割点】【C++算法】928. 尽量减少恶意软件的传播 II
|
1天前
|
算法
讲课:拓扑排序、最短路算法
讲课:拓扑排序、最短路算法
|
5天前
|
算法 索引
数据结构与算法-最小生成树入门
数据结构与算法-最小生成树入门
11 0
|
5天前
|
算法 索引
数据结构与算法-排序进阶入门
数据结构与算法-排序进阶入门
7 0
|
5天前
|
算法
数据结构与算法-AVL树入门
数据结构与算法-AVL树入门
9 0
|
5天前
|
算法 索引
数据结构与算法-三种队列基础入门
数据结构与算法-三种队列基础入门
8 0
|
16天前
|
存储 机器学习/深度学习 算法
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
19 1
|
19天前
|
机器学习/深度学习 人工智能 算法
分类算法入门:以鸢尾花数据集为例(上)
分类算法入门:以鸢尾花数据集为例(上)
30 2
|
19天前
|
机器学习/深度学习 算法 数据可视化
分类算法入门:以鸢尾花数据集为例(下)
分类算法入门:以鸢尾花数据集为例(下)
38 2
|
11天前
|
机器学习/深度学习 人工智能 算法
基于DCT和扩频的音频水印嵌入提取算法matlab仿真
本文介绍了结合DCT和扩频技术的音频水印算法,用于在不降低音质的情况下嵌入版权信息。在matlab2022a中实现,算法利用DCT进行频域处理,通过扩频增强水印的隐蔽性和抗攻击性。核心程序展示了水印的嵌入与提取过程,包括DCT变换、水印扩频及反变换步骤。该方法有效且专业,未来研究将侧重于提高实用性和安全性。