拓朴排序与动态规划

2024-03-21 08:40
文章标签 动态 规划 排序 拓朴

本文主要是介绍拓朴排序与动态规划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、知识部分

1 概念

如果一个有向图无法从某个顶点出发经过若干条边回到该点,则这个图是一个有向无环图(DAG图)。
拓扑排序指是将一个DAG图中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边 < u , v > ∈ E ( g ) \lt u,v\gt \in E(g) <u,v>∈E(g),则u在线性序列中出现在v之前。

2 实现

Step 1:选择一个入度为0的点输出;
Step2:删除此节点及其所有出边;
Step3:重复执行1,2,直至图空。
例:
原图:

输出0。

输出1。
在这里插入图片描述
输出3

输出2。

输出4。
此时图空了,拓扑序列为0,1,3,2,4

2.1 使用BFS

首先将入度为0的顶点入队;
while(队列不空){队头的所有邻接点入度-1;如果存在邻接点入度变为0时则入队;出队;
}
出队序列就是拓扑序列;

这样得到的拓扑序列不唯一。那如何使拓扑序列的字典序最小呢?
将队列替换为优先队列

2.2 使用DFS

每次都沿着一条路径一直向下搜索,直到某个顶点出度为0被标记已经访问,就停止递归,往回走,在回来的路上记录拓扑排序,即后序遍历。(所以我们得到的序列的反着的,反转一下就好了)

二、实践

1 家谱树

1.1 题目描述

请你整理一下一个家谱。 给出每个人的孩子的信息。 输出一个序列,使得每个人的后辈都比那个人后列出。
第1行一个整数 N ( 1 ≤ N ≤ 100 ) N(1 \le N \le 100) N(1N100) ,表示家族的人数; 接下来 N N N 行,第 I I I 行描述第 I I I 个人的儿子; 每行最后是0表示描述完毕。
如果有多解输出字典序最小的解。

1.2 思路

字典序最小,使用优先队列。
用vector更简洁。

1.3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("___OK___")
#define pr printf("\n")
#define pa printf("A: ")
#define pi acos(-1.0)
using namespace std;
priority_queue<int,vector<int>,greater<int> > q;
int n;
vector<vector<int> >e(1000);
int d[1002];
void bfs(){//入队for(int i=1;i<=n;i++){if(d[i]==0){q.push(i);}}while(!q.empty()){ll k=q.top();q.pop();printf("%d ",k);for(int i=0;i<e[k].size();i++){d[e[k][i]]--;//队头的所有邻接点入度--if(!d[e[k][i]]){q.push(e[k][i]);}}}
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++){int x;while(scanf("%d",&x)&&x!=0){//i到x有一条边e[i].push_back(x);d[x]++;//记录每个点的入度}}bfs();return 0;
}

2 食物链2

2.1 题目描述

现在给你 n n n 个物种和 m m m 条能量流动关系,求其中的食物链条数。物种的名称为从 1 1 1 n n n 编号 M M M 条能量流动关系形如 a 1 , b 1 , a 2 , b 2 , a 3 , b 3 , … , a m − 1 , b m − 1 , a m , b m a_1,b_1,a_2,b_2,a_3,b_3,\ldots,a_{m-1},b_{m-1},a_m,b_m a1,b1,a2,b2,a3,b3,,am1,bm1,am,bm。其中 a i a_i ai b i b_i bi 表示能量从物种 a i a_i ai 流向物种 b i b_i bi,注意单独的一种孤立生物不算一条食物链。

2.2 思路

入度为零的点的方案数为1,其余的点的方案数等于指向它的点的方案数之和,最后统计出度为0的点的方案数,累加即可。
此时用了一点点DP。
注意到单独的一种孤立生物不算一条食物链,那么在一开始入度为零的点进入队列时要判断一下,不让那些没有出度的点进入队列。

2.3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("___OK___")
#define pr printf("\n")
#define pa printf("A: ")
#define pi acos(-1.0)
using namespace std;
const int N=1000010;
ll n,m,f[N],d[N];
vector<ll> e[N];
ll ans;
ll bfs(){queue<ll> q;for(int i=1;i<=n;i++){if(!d[i]&&e[i].size()){q.push(i);f[i]=1; }}	while(!q.empty()){ll x=q.front();q.pop();if(!e[x].size()){ans+=f[x];}for(int i=0;i<e[x].size();i++){ll t=e[x][i];f[t]+=f[x];d[t]--;if(!d[t]){q.push(t);}}}return ans;
}
int main(){cin>>n>>m;for(int i=1;i<=m;i++){ll x,y;cin>>x>>y;d[y]++;e[x].push_back(y);}cout<<bfs();return 0;
}

这篇关于拓朴排序与动态规划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/832246

相关文章

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

golang实现动态路由的项目实践

《golang实现动态路由的项目实践》本文主要介绍了golang实现动态路由项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习... 目录一、动态路由1.结构体(数据库的定义)2.预加载preload3.添加关联的方法一、动态路由1

Java List排序实例代码详解

《JavaList排序实例代码详解》:本文主要介绍JavaList排序的相关资料,Java排序方法包括自然排序、自定义排序、Lambda简化及多条件排序,实现灵活且代码简洁,文中通过代码介绍的... 目录一、自然排序二、自定义排序规则三、使用 Lambda 表达式简化 Comparator四、多条件排序五、

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序

Python Selenium动态渲染页面和抓取的使用指南

《PythonSelenium动态渲染页面和抓取的使用指南》在Web数据采集领域,动态渲染页面已成为现代网站的主流形式,本文将从技术原理,环境配置,核心功能系统讲解Selenium在Python动态... 目录一、Selenium技术架构解析二、环境搭建与基础配置1. 组件安装2. 驱动配置3. 基础操作模