848. 有向图的拓扑序列(BFS应用)

题目所属分类

属于BFS
有向无环图一定是拓扑序列,有向有环图一定不是拓扑序列
时间复杂度 O(n+m) , n表示点数,m 表示边数

原题链接

在这里插入图片描述

代码案例:输入样例:
3 3
1 2
2 3
1 3
输出样例:
1 2 3

题解

有向无环图 一定存在拓扑序列
本题的意思就是看一看是否为有向无环图 如果是 就输出这个拓扑序列
因为
一个有向无环图 至少存在一个入度为0的点
然后在有向无环图中删掉一个点 依旧是有向无环图 所以删掉最后 全删干净了 那么这个就是拓扑序列 拓扑序列放在队列中 队列里面加入所有入读为0 的点

普及知识

在这里插入图片描述

题解思路

在这里插入图片描述

题解过程

在这里插入图片描述
开始时,图是这样的状态,发现A的入度为 0,所以删除A和A上所连的边,结果如下图:
在这里插入图片描述
这时发现B的入度为 0,C的入度为 0,所以删除B和B上所连的边、C和C上所连的边,结果如下图:
在这里插入图片描述
这时发现发现D的入度为 0,所以删除D和D上所连的边(如果有就删),结果如下图:
这时发现发现D的入度为 0,所以删除D和D上所连的边(如果有就删),结果如下图:

【空】

这时整个图被删除干净,所有能进行拓扑排序。
解题思路

  • 首先记录各个点的入度

  • 然后将入度为 0 的点放入队列

  • 将队列里的点依次出队列,然后找出所有出队列这个点发出的边,删除边,同事边的另一侧的点的入度 -1。

  • 如果所有点都进过队列,则可以拓扑排序,输出所有顶点。否则输出-1,代表不可以进行拓扑排序。

import java.util.*;
public class Main{
    static int N =  100010,n,m,hh,tt,idx;
    static int[] e = new int[N],ne = new int[N],h = new int[N];
    static int[] q = new int[N];//数组模拟队列
    static int[] d = new int[N];//保存各个点的入度
    public static void add(int a,int b){
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx++;
    }
    static boolean topsort(){
        hh = 0; tt = -1 ;
        for(int i = 1 ; i <= n ; i++){
            if(d[i] == 0){
                 q[++tt] = i ;//把入度为0 的点放入队列中
            }
        }
          
        while(hh <= tt){
            int t = q[hh++];
            for(int i = h[t] ; i != -1 ; i =ne[i]){//遍历边
                int j = e[i] ;
                 d[j] -- ;//删掉t->j 就是使得它的入度-1
                if(d[j] == 0){
                    q[++tt] = j ;//如果减完之后s的入度数为0;就将他插入队列中
                }
            }
        }
         return tt == n - 1; //说明队列中一共进了n个点  所有的点都入队列了
    }

 public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        m = scan.nextInt();
        for(int i = 0 ; i < N ; i ++ ){
            h[i] = -1; 
        }
        while(m -- > 0){
            int a = scan.nextInt();
            int b = scan.nextInt();
            add(a,b);
            d[b] ++;
        }
        
        if(topsort()){//判断是否是拓扑序列
             for(int i = 0 ; i < n; i ++ ){  
                 //队列刚好队头删除的点就是我们的拓扑序列,因为我们只是将hh往后面移动,但是它具体前面的值还在,直接输出就行
                System.out.print(q[i] + " ");
            }
        }else{
             System.out.println("-1");
        }
}
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1 目录 一.数论.... 4 1.阶乘最后非零位 ...... 4 2. 模线性方程(组) ..... 4 3. 素数表.. 6 4. 素数随机判定(miller_rabin) .. 6 5. 质因数分解 .. 7 6. 最大公约数欧拉函数 ... 8 二.图论_匹配 . 9 1. 二分图最大匹配(hungary 邻接表形式) ..... 9 2. 二分图最大匹配(hungary 邻接表形式,邻接阵接口) ...... 10 3. 二分图最大匹配(hungary 邻接阵形式) ... 10 4. 二分图最大匹配(hungary 正向表形式) ... 11 5. 二分图最佳匹配(kuhn_munkras 邻接阵形式) .. 11 6. 一般图匹配(邻接表形式) . 12 7. 一般图匹配(邻接表形式,邻接阵接口) .... 13 8. 一般图匹配(邻接阵形式) . 14 9. 一般图匹配(正向表形式) . 15 三.图论_生成树 ... 16 1. 最小生成树(kruskal 邻接表形式) ..... 16 2. 最小生成树(kruskal 正向表形式) ..... 17 3. 最小生成树(prim+binary_heap 邻接表形式) ..... 19 4. 最小生成树(prim+binary_heap 正向表形式) ..... 20 5. 最小生成树(prim+mapped_heap 邻接表形式) .. 21 6. 最小生成树(prim+mapped_heap 正向表形式) .. 22 7. 最小生成树(prim 邻接阵形式)... 23 8. 最小树形图(邻接阵形式) . 24 四.图论_网络流 ... 25 1. 上下界最大流(邻接表形式) 25 2. 上下界最大流(邻接阵形式) 26 3. 上下界最小流(邻接表形式) 27 4. 上下界最小流(邻接阵形式) 29 5. 最大流(邻接表形式) .. 30 6. 最大流(邻接表形式,邻接阵接口) ..... 31 7. 最大流(邻接阵形式) .. 32 8. 最大流无流量(邻接阵形式) 32 9. 最小费用最大流(邻接阵形式) ... 33 五. 图论_最短路径 34 1. 最短路径(单源bellman_ford 邻接阵形式) . 34 2. 最短路径(单源dijkstra_bfs 邻接表形式) 35 3. 最短路径(单源dijkstra_bfs 正向表形式) 35 4. 最短路径(单源dijkstra+binary_heap 邻接表形式) .. 36 2 5. 最短路径(单源dijkstra+binary_heap 正向表形式) .. 37 6. 最短路径(单源dijkstra+mapped_heap 邻接表形式) 38 7. 最短路径(单源dijkstra+mapped_heap 正向表形式) 39 8. 最短路径(单源dijkstra 邻接阵形式) 40 9. 最短路径(多源floyd_warshall 邻接阵形式) ..... 40 六. 图论_连通性 .... 41 1. 无向图关键边(dfs 邻接阵形式) . 41 2. 无向图关键点(dfs 邻接阵形式) . 42 3. 无向图块(bfs 邻接阵形式) .. 43 4. 无向图连通分支(bfs 邻接阵形式) .... 43 5. 无向图连通分支(dfs 邻接阵形式) .... 44 6. 有向图强连通分支(bfs 邻接阵形式) 44 7. 有向图强连通分支(dfs 邻接阵形式) 45 8. 有向图最小点基(邻接阵形式) ... 46 七. 图论_应用 46 1.欧拉回路(邻接阵形式) 46 2. 前序表转化 47 3. 树的优化算法 ...... 48 4. 拓扑排序(邻接阵形式). .... 49 5. 最佳边割集 50 6. 最佳顶点割集 ...... 51 7. 最小边割集 52 8. 最小顶点割集 ...... 53 9. 最小路径覆盖 ...... 55 八. 图论_NP 搜索.. 55 1. 最大团(n 小于64)(faster).. 55 2. 最大团 58 九. 组合... 59 1. 排列组合生成 ...... 59 2. 生成gray 码 . 60 3. 置换(polya) 61 4. 字典序全排列 ...... 61 5. 字典序组合 62 6. 组合公式.... 62 十. 数值计算.. 63 1. 定积分计算(Romberg) ...... 63 2. 多项式求根(牛顿法) .. 64 3. 周期性方程(追赶法) .. 66 十一. 几何...... 67 1. 多边形 67 2. 多边形切割 70 3. 浮点函数.... 71 4. 几何公式.... 76 5. 面积.... 78 3 6. 球面.... 79 7. 三角形 79 8. 三维几何.... 81 9. 凸包(graham) 89 10. 网格(pick) 91 11. 圆 ...... 92 12. 整数函数.. 94 13. 注意.. 96 十二. 结构...... 97 1. 并查集 97 2. 并查集扩展(friend_enemy) .. 98 3. 堆(binary) ... 98 4. 堆(mapped) 99 5. 矩形切割.... 99 6. 线段树...... 100 7. 线段树扩展 . 102 8. 线段树应用 . 105 9. 子段和...... 105 10. 子阵和.... 105 十三. 其他.... 106 1. 分数.. 106 2. 矩阵.. 108 3. 日期.. 110 4. 线性方程组(gauss) ... 111 5. 线性相关.. 113 十四. 应用.... 114 1. joseph 114 2. N 皇后构造解 ..... 115 3. 布尔母函数 . 115 4. 第k 元素.. 116 5. 幻方构造.. 116 6. 模式匹配(kmp) .. 118 7. 逆序对数.. 118 8. 字符串最小表示 119 9. 最长公共单调子序列 ...... 119 10. 最长子序列 ...... 120 11. 最大子串匹配 .. 121 12. 最大子段和 ...... 122 13. 最大子阵和 ...... 123

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依嘫_吃代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值