拓扑排序

leetcdoe课程表

▼魔方 西西 提交于 2020-01-26 13:09:46
题目 现在你总共有 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 完成。 代码(java) 方法一:入度表(广度优先遍历) class Solution { public boolean canFinish ( int numCourses , int

基于邻接矩阵的拓扑排序

删除回忆录丶 提交于 2020-01-25 19:48:26
总结下算法好了: (1)构图:每个活动是一个顶点,如果A必须排在B前面,那么有边从顶点A指向顶点B,顶点B的入度+1 (2)遍历所有顶点,将入度为0的顶点入栈 (3)如果栈不为空,则将栈顶出栈,然后将该顶点从图中删掉,即该点指向的点的入度-1,如果减后为0则入栈,重复(3) 简单版的代码,只能举出一种拓扑排序: 1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAX_VERTEX_NUM 100 5 6 int ver_num; 7 char vertex[MAX_VERTEX_NUM]; 8 int indeg[MAX_VERTEX_NUM]; 9 int graph[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 10 11 void CreateMGragh() 12 { 13 int i,j; 14 int n1,n2,f1,f2; 15 char ch1,ch2,ch3; 16 while(1){ 17 scanf("%c%c%c",&ch1,&ch2,&ch3); 18 f1 = f2 = 0; 19 for (i=0; vertex[i] != 0; i++){ 20 if (vertex[i] == ch1){ 21 f1 = 1; 22 n1 = i; 23 break; 24 }

Java数据结构与算法精讲

被刻印的时光 ゝ 提交于 2020-01-23 03:19:40
课程简介 本系列视频教程为数据结构与算法基础,使用java语言描述,适合没有学过C/C++有一定Java基础的同学。没有Java基础的同学可以先行学习Java基础。 课程目录 ├─线性表 ├─栈和队列 ├─HashMap和LinkedHashMap ├─树 ├─二叉树 ├─图 ├─图的遍历与最小生成树 ├─图的最短路径与拓扑排序 ├─算法简介 ├─算法排序 ├─排序与归并 ├─递归与穷举 ├─贪心和分治 ├─动态规划和回溯 来源: CSDN 作者: di_pingxian 链接: https://blog.csdn.net/di_pingxian/article/details/103897423

拓扑排序

☆樱花仙子☆ 提交于 2020-01-22 20:28:46
拓扑排序是选择入度为 \(0\) 的点来进行 \(bfs\) 的一个过程,求出拓扑序列 点之间的关系有并列关系和先后关系,因为并列关系的存在,所以拓扑序列不一定是唯一的 \(code\) : void topo() { queue<node> q; for(int i=1;i<=n;++i) if(!ru[i]) q.push(i); while(!q.empty()) { node p=q.front(); t[++to_cnt]=p; int x=p.num,top=p.top; for(int i=head[x];i;i=e[i].nxt) { int y=e[i].to; ru[y]--; if(!ru[y]) q.push((node){y,top+1}); } q.pop(); } } 车站分级 ,巧妙建图,然后用拓扑的性质得出答案 菜肴制作 ,建反图跑拓扑 来源: https://www.cnblogs.com/lhm-/p/12229470.html

POJ 1088 滑雪(拓扑排序)

耗尽温柔 提交于 2020-01-22 02:03:31
题目: 1088 题意:求矩阵中的最长递减长度 题解:拓扑排序(剥洋葱) AC代码: #include<iostream> #include<vector> using namespace std; #define MAX 100 int cnt; int dir[4][2] = { {0,1}, {0,-1}, {1, 0}, {-1, 0} }; int matrix[MAX][MAX]; int outdegree[MAX][MAX] = {0}; vector<int> v; int main() { int r, c; int tx, ty; //坐标的临时变量 cnt = 0; cin >> r >> c; for (int i = 0; i < r; i++) for (int j = 0; j < c; j++) cin >> matrix[i][j]; for (int i = 0; i < r; i++) //计算所有点的出度 for (int j = 0; j < c; j++) for (int k = 0; k < 4; k++) { tx = i + dir[k][0]; ty = j + dir[k][1]; if (tx < r && tx >= 0 && ty < c && ty >= 0 && matrix[i][j] < matrix[tx]

12_3拓扑排序

落花浮王杯 提交于 2020-01-20 15:29:29
任务调度: 从task.in 文件中读入任务调度序列,输出n个任务适合的一种调度方式到task.out中。每行第一个表示前序任务,括号中的任务为若干个后序任务,表示只有在前序任务完成的情况下,后序任务才能开始。若后序为NULL则表示无后继任务。 Sample Input: Task0 ( Task1 , Task2 ) Task1 ( Task3 ) Task2 ( NULL ) Task3 ( NULL ) Sample Output: Task0 Task1 Task3 Task2 知识点: 从字符串中提取数字 拓扑排序 AC代码 # include <stdio.h> # include <cstring> # include <algorithm> # include <vector> # define maxn 1000 using namespace std ; vector < int > G [ maxn ] ; int n = 0 ; int InDegree [ maxn ] = { 0 } ; void TopoSort ( ) { int Q [ maxn ] ; int front = - 1 , rear = - 1 ; int u ; for ( int i = 0 ; i < n ; i ++ ) { if ( InDegree [ i ] == 0

题解——Acwing.342 道路与航线

左心房为你撑大大i 提交于 2020-01-18 08:25:16
说在前面   首先这题单纯从数据出发的话,直接做SPFA,加点优化,SLF或者LLL的话是可以直接过的。   但是,本着 科学严谨的态度 ,极其不推荐使用这种投机取巧的偷懒方式。而且如果数据是特殊构造的话,就算加了优化也一样会被卡。故此处介绍正解。 算法介绍 算法描述:   考虑到本题有个非常好的性质:有向边必然无环。   先不考虑有向边,则所有无向边加点集构成的图就是数个连通块。   考虑有向边,将每个连通块看成点,每条有向边就是这些点之间的连边,则整张图构成一张有向无环图,可以直接拓扑排序遍历。   对于每个连通块内部,直接做Dijkstra即可。 算法流程:   先读入无向边,然后处理连通块,记录每个点所属的连通块编号以及每个连通块所包含的所有点。   再读入有向边,记录每个连通块的入度。   先找到入度为0的连通块,然后开始拓扑排序。   对于遍历到的每一个连通块,做一遍Heap_Dijkstra。在进行松驰操作时,判断两点是否在同一个连通块内,若是,则将其放入Heap中,否则将所指向的点所属连通块入度减1,然后将其放入拓扑队列中即可。 时间复杂度分析:   连通块处理和拓扑排序都是线性的,整个算法时间上的瓶颈就在于Dijkstra。   设连通块x内点数为nx,边数为mx。   则所有Dijstra的总时间为:m1logn1+m2logn2+……+mslogns<

拓扑排序

谁说胖子不能爱 提交于 2020-01-16 19:54:39
条件:必须在有向无环图中(DAG)中。 使用dfs来对DAG求出拓扑排序。 例题和代码: 例题: https://vjudge.net/problem/UVA-10305#author=0 代码: #include <iostream> #include <cstdio> #include <map> #include <string> #include <vector> #include <algorithm> #include <sstream> #include <cstring> #include <cmath> #include <stack> #include <queue> using namespace std; const int maxn = 110; int matrix[maxn][maxn]; // 0:未访问 -1:正在访问 1:已访问 int vis[maxn]; int topo[maxn], tt; // 拓扑dfs bool dfs(int m, int u) { vis[u] = -1; for(int i = 1; i <= m; i++) { if(matrix[u][i]) { // 存在有向环 if(vis[i] == -1) return false; if(!vis[i]) { bool flag = dfs(m, i); if(

DFS及有向图的拓扑排序

痴心易碎 提交于 2020-01-16 14:59:50
一个有向图的DFS森林可能具有的全部类型的边: 树向边、回边、从顶点到树中非子女子孙的前向边、交叉边。所有不属于前三种类型的边都属于交叉边。 一条回边的存在意味着有向图具有一个有向的回路。如果一个有向图的DFS森林没有回边,该有向图是一个无环有向图,即有向无环图的简称。 拓扑排序: 按某种次序列出有向图中的顶点,使得对于图中每一条边来说,边的起始顶点总是排在边的结束顶点之前。这个问题称为拜年排序。 拓扑排序的两个算法: 1,DFS。 执行一次DFS遍历,并记住顶点变成死端(即退出遍历栈)的顺序。将该顺序反过来就得到了拓扑排序的一个解。当然,在遍历的时候不能遇到回边。如果遇到一条回边,该图就不是无环有向图,并且对它顶点的拓扑排序是不可能的。 2,基于减治法: 不断地做这样的一件事,在余下的有向图中求出一个源,它是一个没有输入边的顶点,然后把它和所有从它出发的边都删除。如果有多个这样的源,可以任意选择一个。如果这样的源不存在,算法停止,因为该问题是无解的。 来源: https://www.cnblogs.com/cmleung/archive/2011/04/26/2028872.html

算法总结之拓扑排序

偶尔善良 提交于 2020-01-16 14:07:13
拓扑排序 1.一般应用 拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。例如,在日常工作中,可能会将项目拆分成A、B、C、D四个子部分来完成,但A依赖于B和D,C依赖于D。为了计算这个项目进行的顺序,可对这个关系集进行拓扑排序,得出 一个线性的序列 ,则排在前面的任务就是需要先完成的任务。 2.实现的基本方法   (1)从有向图中选择一个没有前驱(即 入度为0 )的顶点并且输出它.   (2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.   (3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止. 3.C++版本实现 1 /*以邻接矩阵Edge[A][B]=N存放图信息:A指向B,权值为N*/ 2 /*假设不相连的边的Edge==INT_MAX*/ 3 void Topo() 4 { 5 sort(Edge+1,Edge+N+1); 6 for (int i=1; i<=N; i++) 7 { 8 int j; 9 for (j=1; j<=N; i++) //vis为标记数组,标记是否已经存在在Topo数组中 10 if (!vis[j]&&!in[j]) //in数组表示的下标顶点的入度 11 { 12 Topo[i]=j; 13 vis[j]=1; 14 break; 15 } 16 for (int k=1;k<=N;k++) /