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

代码随想录算法训练营day58:图论08:拓扑排序精讲;dijkstra(朴素版)精讲

拓扑排序精讲

卡码网:117. 软件构建(opens new window)

题目描述:

某个大型软件项目的构建系统拥有 N 个文件,文件编号从 0 到 N - 1,在这些文件中,某些文件依赖于其他文件的内容,这意味着如果文件 A 依赖于文件 B,则必须在处理文件 A 之前处理文件 B (0 <= A, B <= N - 1)。请编写一个算法,用于确定文件处理的顺序。

输入描述:

第一行输入两个正整数 M, N。表示 N 个文件之间拥有 M 条依赖关系。

后续 M 行,每行两个正整数 S 和 T,表示 T 文件依赖于 S 文件。

输出描述:

输出共一行,如果能处理成功,则输出文件顺序,用空格隔开。

如果不能成功处理(相互依赖),则输出 -1。

分析:

应用场景:对于复杂的依赖关系,给出线性的依赖顺序

eg:大学排课,例如 先上A课,才能上B课,上了B课才能上C课,上了A课才能上D课,等等一系列这样的依赖顺序。 问给规划出一条 完整的上课顺序。

概括来说,给出一个 有向图,把这个有向图转成线性的排序 就叫拓扑排序

当然拓扑排序也要检测这个有向图 是否有环,即存在循环依赖的情况,因为这种情况是不能做线性排序的。

所以拓扑排序也是图论中判断有向无环图的常用方法

思路 bfs:

**初始化:

因为是有向,可以用邻接表记录

需要记录每个结点的入度(在vnode里可以记录,注意s->t的边,t的innode++),和每个结点的依赖关系

for循环:循环n次,因为要把所有的点都取出来

1、找开头 入度为0的结点,加入结果集

**开头的结点入度=0

找入度为0 的节点,我们需要用一个队列放存放。

因为每次寻找入度为0的节点,不一定只有一个节点,可能很多节点入度都为0,所以要将这些入度为0的节点放到队列里,依次去处理。

加入队列之后,入度改为-1,这样不会重复影响结果

2、把这个结点从图上去掉

反复,直到所有节点都被删除

实际上操作时,要把 该节点作为出发点所连接的节点的 入度 减一。

eg:准备删0,那就是把1和2的结点入度-1

判断有向环的方式:

如果我们发现结果集元素个数 不等于 图中节点个数,我们就可以认定图中一定有 有向环!

#include <math.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>typedef struct arcnode{int node;struct arcnode *nextnode;
}Arcnode;typedef struct {int into;Arcnode *firstarc;
}Vnode;typedef struct {Vnode list[1000];
}graph;int main(){int n,m;scanf("%d%d",&n,&m);graph* g=(graph* )malloc(sizeof(graph));//用邻接表for(int i=0;i<n;i++) g->list[i].firstarc=NULL;for(int i=0;i<n;i++) g->list[i].into = 0;for(int i=0;i<m;i++){int s,t;scanf("%d%d",&s,&t);Arcnode *p=(Arcnode *)malloc(sizeof(Arcnode));p->node=t;p->nextnode=g->list[s].firstarc;g->list[s].firstarc = p;g->list[t].into++;}int queue[60000];int front=-1,rear=-1;int count=0;int *ans = (int*)malloc(sizeof(int)*n);for(int i=0;i<=n-1;i++){for(int j=0;j<n;j++){//所有入度为0的结点都进队if(g->list[j].into==0){rear++;queue[rear]=j;g->list[j].into=-1;}}front++;//出一个入度为0的结点,并且记录int s = queue[front];ans[count++]=s;Arcnode*p = g->list[s].firstarc;//把以该结点为起点,终点处的入度都-1while(p!=NULL){int w = p->node;g->list[w].into--;p=p->nextnode;}}if(count!=n) printf("-1");else {for(int i=0;i<n-1;i++) printf("%d ",ans[i]);printf("%d",ans[n-1]);}return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [C++进阶]map和set的相关题目
  • 数据结构-c/c++实现栈(详解,栈容量可以动态增长)
  • MySQL——基础操作
  • 【Unity】简单机甲运动系统——坦克式操控方式
  • 房产报备小程序房产报备系统源码搭建方案
  • GPT-SoVITS-WebUI 初体验
  • 专栏引言:迈向大数据分析的最前沿
  • Java 单元测试指南
  • Nginx IP 哈希负载均衡配置:实现请求智能分发
  • WebForms DataList 控件深入解析
  • Vulnhub靶场 | DC系列 - DC7
  • Vue3安装Element Plus
  • 怎样通过bs4找出程序中 标签<div class=“List2“>中所有的<li>的内容?
  • 【计算机网络】计算机网络的性能指标
  • 5.3二叉树——二叉树链式结构实现
  • eclipse的离线汉化
  • JavaScript创建对象的四种方式
  • Laravel 中的一个后期静态绑定
  • PhantomJS 安装
  • tweak 支持第三方库
  • Xmanager 远程桌面 CentOS 7
  • 安卓应用性能调试和优化经验分享
  • 产品三维模型在线预览
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 检测对象或数组
  • 经典排序算法及其 Java 实现
  • 深入浏览器事件循环的本质
  • -- 数据结构 顺序表 --Java
  • 小程序01:wepy框架整合iview webapp UI
  • 源码安装memcached和php memcache扩展
  • HanLP分词命名实体提取详解
  • Java数据解析之JSON
  • MPAndroidChart 教程:Y轴 YAxis
  • 阿里云API、SDK和CLI应用实践方案
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • # 透过事物看本质的能力怎么培养?
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (STM32笔记)九、RCC时钟树与时钟 第二部分
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (九)c52学习之旅-定时器
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (十三)Flink SQL
  • (一)SvelteKit教程:hello world
  • .NET DataGridView数据绑定说明
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .Net(C#)自定义WinForm控件之小结篇
  • .Net小白的大学四年,内含面经
  • .NET中使用Redis (二)