当前位置: 首页 > news >正文

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");
        }
}
 }

相关文章:

  • 物联网开发笔记(8)- 使用Wokwi仿真ESP32开发板实现模数转换和脉宽调制
  • 古怪的Lucene中文分词方案 —— CJKAnalyzer
  • SPDK vhost-user结合SPDK NVMe-oF RDMA性能调优
  • mysql 创建函数
  • 支持十亿级密态数据、低代码,蚂蚁集团发布隐语开放平台
  • 关于kafka常见名词解释,你了解多少?
  • 吴恩达深度学习笔记(四)——深度学习的实践层面
  • KNN-KG论文学习笔记
  • DOM与BOM与Echarts
  • 13c++呵呵老师【pawn移动组件与碰撞】
  • 简明介绍 n-gram
  • 前端培训丁鹿学堂:es7_es11常用新特性(三)
  • 深入浅出总结求解菲波那切数列的五种方法
  • TCP滑动窗口机制(重要)
  • [2008][note]腔内级联拉曼发射的,二极管泵浦多频调Q laser——
  • [数据结构]链表的实现在PHP中
  • Android 控件背景颜色处理
  • Angular 2 DI - IoC DI - 1
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • java 多线程基础, 我觉得还是有必要看看的
  • Java方法详解
  • mac修复ab及siege安装
  • Mysql优化
  • SQLServer之创建显式事务
  • TypeScript实现数据结构(一)栈,队列,链表
  • Webpack 4 学习01(基础配置)
  • 类orAPI - 收藏集 - 掘金
  • 前端之React实战:创建跨平台的项目架构
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 用Python写一份独特的元宵节祝福
  • 字符串匹配基础上
  • No resource identifier found for attribute,RxJava之zip操作符
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • const的用法,特别是用在函数前面与后面的区别
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (论文阅读11/100)Fast R-CNN
  • (强烈推荐)移动端音视频从零到上手(下)
  • *1 计算机基础和操作系统基础及几大协议
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .bashrc在哪里,alias妙用
  • .NET Standard 的管理策略
  • .net 后台导出excel ,word
  • .NetCore 如何动态路由
  • .net访问oracle数据库性能问题
  • .NET开发者必备的11款免费工具
  • [20150629]简单的加密连接.txt
  • [Android]通过PhoneLookup读取所有电话号码
  • [Angularjs]ng-select和ng-options
  • [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体
  • [CareerCup] 13.1 Print Last K Lines 打印最后K行
  • [CC-FNCS]Chef and Churu