拓扑排序

LeetCode_207课程表

我是研究僧i 提交于 2019-12-13 16:42:13
现在你总共有 n 门课需要选,记为 0 到 n-1。 在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] 给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习? 示例 1: 输入: 2, [[1,0]] 输出: true 解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。 示例 2: 输入: 2, [[1,0],[0,1]] 输出: false 解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。 说明: 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。 你可以假定输入的先决条件中没有重复的边。 提示: 这个问题相当于查找一个循环是否存在于有向图中。如果存在循环,则不存在拓扑排序,因此不可能选取所有课程进行学习。 通过 DFS 进行拓扑排序 - 一个关于Coursera的精彩视频教程(21分钟),介绍拓扑排序的基本概念。 拓扑排序也可以通过 BFS 完成。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/course-schedule 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

图的拓扑排序(动图)

≯℡__Kan透↙ 提交于 2019-12-11 20:05:44
文章目录 概述 度的定义 排序 描述 示例 示例动图 伪代码 概述 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。 度的定义 入度,顶点的入边条数 出度,顶点的出边条数 排序 描述 创建一个队列,保存拓扑排序的顺序 遍历整张图,计算出每一个顶点的入度,并找到入度为0的顶点,将该点加入队列 取出队列头部的顶点,所有指向该顶点的入度都减1,减1后入度为0的顶点加入队列,重复本步操作,直到队列中再没有元素 示例 图中并没有画出队列,排序结果展示的是出队列的顺序 遍历完图后,各个顶点的入度,如图所示,再将入度为0的顶点加入队列(顶点0) 取出队列头部的顶点(顶点0),所有指向该顶点的入度都减1,再将入度为0的顶点加入队列(顶点1) 取出队列头部的顶点(顶点1),所有指向该顶点的入度都减1,再将入度为0的顶点加入队列(顶点2,4) 取出队列头部的顶点(顶点2),由于此时顶点2没有指向顶点了,所以没有顶点入队列 取出队列头部的顶点(顶点4)

D - Digi Comp II ( 拓扑排序 )

喜你入骨 提交于 2019-12-11 09:02:12
D - Digi Comp II ( 拓扑排序 ) 题意:给定M个开关,每个开关有初始状态(L或者R),每个开关有两个走向,分别指向左边对应的开关和右边对应的开关。 一个球走到当前开关,会走向当前状态指向的方向,并且使当前的状态改变。 问N个球从1号出发,最终每个开关的状态。 给定的关系是个DAG,除了0号都有两个出度,可以看成左右儿子。 思路:模拟一下,不难发现,如果X个球经过i节点,那么将会有X/2+X%2次走向初始方向,X/2次走向另外一个方向。即是topo排序一下可以搞。 注:不一定只要1号点入度为0,题目只保证了除0之外,出度为2;没保证入度(这一点感觉题目的确误导了很多读题人)。 所以必须开始把入度为0的都加进queue去,不然有的点跑不到。 注意:拓扑排序一定要注意,刚开始需要把所有入度为0的点全push进去。 代码: #include <bits/stdc++.h> #define int long long using namespace std; const int maxn = 5e5+10; int state[maxn]; int num[maxn]; vector<int> G[maxn]; int du[maxn]; int n,m; signed main() { int l,r; char op; ios::sync_with_stdio

图论--拓扑排序--模板

懵懂的女人 提交于 2019-12-11 05:23:02
//字典序号最小 # include <cstdio> # include <cstring> # define MAXN 517 int G [ MAXN ] [ MAXN ] ; //路径 int in_degree [ MAXN ] ; //入度 int ans [ MAXN ] ; int n , m , x , y ; int i , j ; bool toposort ( ) { for ( i = 1 ; i <= n ; i ++ ) //从最小的开始寻找, { //这样保证了有多个答案时序号小的先输出 int k = 1 ; while ( in_degree [ k ] != 0 && k <= n ) //寻找入度为零的点 k ++ ; if ( k == n + 1 ) return 0 ; ans [ i ] = k ; in_degree [ k ] = - 1 ; //更新为-1,后边检测不受影响,相当于删除节点 for ( int j = 1 ; j <= n ; j ++ ) { if ( G [ k ] [ j ] ) in_degree [ j ] -- ; //相关联的入度减1 } } return 1 ; } void init ( ) { memset ( in_degree , 0 , sizeof ( in_degree ) ) ;

图论--拓扑排序--HDU-1285确定比赛名次

好久不见. 提交于 2019-12-10 11:25:09
Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。 Input 输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。 Output 给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。 其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。 Sample Input 4 3 1 2 2 3 4 3 Sample Output 1 2 4 3 裸的字典序最小拓扑排序 # include <cstdio> # include <cstring> # define MAXN 517 int G [ MAXN ] [ MAXN ] ; //路径 int in_degree [ MAXN ] ; //入度 int ans [ MAXN ] ; int n , m , x , y ; int i

反向拓扑排序

老子叫甜甜 提交于 2019-12-09 20:44:49
对于初始没有进行编号,且要求数字小的尽可能在前面 需要进行反向拓扑排序 真的看不懂 反正需要进行 邻接表优化 传送门 传送门 #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int N = 3e4+5; int n,m,cnt; bool mp[N][N]; int du[N],head[N]; int a[N]; struct P{ int to,nxt; }e[N]; void add(int u,int v){ e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt++; } void topsort(){ int k=n; priority_queue<int>q; for(int i=1;i<=n;i++) if(!du[i]) q.push(i); while(!q.empty()){ int tmp=q.top(); q.pop(); a[tmp]=k--; for(int i=head[tmp];~i;i=e[i].nxt){ int v=e[i].to; du[v]--; if(!du[v]) q.push(v); } } if(k!=0) printf("-1\n");

20182324 2019-2020-1 《数据结构与面向对象程序设计》实验9报告

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-08 22:22:27
20182324 2019-2020-1 《数据结构与面向对象程序设计》实验9报告 课程:《程序设计与数据结构》 班级: 1823 姓名: 殷宇豪 学号: 20182324 实验教师:王志强 实验日期:2019年12月2日 必修/选修: 必修 1.实验内容 1.初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数) 2.图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历) 3.完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环 4.完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出 5.完成有向图的单源最短路径求解(迪杰斯特拉算法) 2. 实验过程及结果 (1)根据屏幕提示初始化无向图和有向图 (2)完成有向图和无向图的遍历 (3)图的拓扑排序 (4)无向图的最小生成树 (5)图的单源最短路径求解 3. 实验过程中遇到的问题和解决过程 问题1:对 Java 中 Iterator 的理解 问题1解决方案: java.util.Iterator 在 JDK 帮助文档中这样阐述:public interface Iterator<E> 对 collection 进行迭代的迭代器。迭代器取代了 Java

20182326 2019-2020-1 《数据结构与面向对象程序设计》实验九报告

混江龙づ霸主 提交于 2019-12-08 21:47:33
20182326 2019-2020-1 《数据结构与面向对象程序设计》实验九报告 课程:《程序设计与数据结构》 班级: 1823 姓名: 刘颖洁 学号:20182326 实验教师:王志强 实验日期:2019年12月2日 必修/选修: 必修 1.实验内容 (1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分) (2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分) (3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分) (4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分) (5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分) 2. 实验过程及结果 (1) 初始化:根据屏幕提示初始化无向图和有向图 (2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历) (3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环 (4) 完成无向图的最小生成树,并输出 (5) 完成有向图的单源最短路径求解 3. 实验过程中遇到的问题和解决过程 问题1: 问题1解决方案: 问题2: 问题2解决方案: 其他(感悟、思考等) 复习了以前的知识

E - Ingredients 拓扑排序+01背包

让人想犯罪 __ 提交于 2019-12-06 05:37:00
题源:https://codeforces.com/gym/101635/attachments 题意: n行,每行给定字符串s1,s2,s3代表一些菜谱名。s2和s3是煮成是的必要条件,然后给出c和v,分别代表s1的消耗和收获;    (注意:这个消耗并不可能是s1的真正消耗和收获,s1的最后消耗和收获是得加上s2和s3的)    然后问在不用超过C消耗的情况下最大收获是多少? 分析:这里我们可以想象到,一道有条件的菜要做成是要若干个“前提”菜做成的,这个过程就是拓扑排序!我们对于每个s1,s2,s3编号后就是拓扑排序了,s2,s3,就是相当于给予s1一个入度;    所有每次拓扑我们就枚举已经做成的s2和s3给最优的c和v给s1,然后最后对所有的菜进行01背包找出答案 #include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const int inf=0x3f3f3f3f; const ll INF=1e18; const int N=1e6+6; const int M=1e5+5; struct node{ int u,id; }; vector<node>g[N]; ll dp[M],cc[M],vv[M],ind[M],book[N]; ll c[N]

HDU1285(拓扑排序裸题

不羁的心 提交于 2019-12-05 09:17:55
。。被多组测试坑了一波 1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 using namespace std; 5 typedef long long ll; 6 const int N = 1e3; 7 vector<int>edge[N]; 8 vector<int> ans; 9 priority_queue<int, vector<int>, greater<int> >q; 10 int n,m,l,r,in[N]; 11 int main(){ 12 ios::sync_with_stdio(0); 13 while(cin>>n>>m){ 14 15 ans.clear();while(!q.empty())q.pop(); 16 for(int i = 1;i <= n;++i){in[i] = 0;edge[i].clear();} 17 18 for(int i = 1;i <= m;++i){ 19 cin>>l>>r; 20 edge[l].push_back(r);in[r]++; 21 } 22 for(int i = 1;i <= n;++i)if(in[i]==0)q.push(i); 23 while(!q.empty()){ 24 int p = q.top();q.pop