[2016-02-18][拓扑排序]

[2016-02-18][拓扑排序]

拓扑排序

  • 思路    dfs
  • 分析
    • 从树的角度来看,就是不同层的节点,顺序是一定的,同层的节点,顺序是不定的,
      • 但是拓扑排序的图不一定是树,可以有环(不能是同向的环,即1->2->3->1 这种)
    • 为了避免漏了节点,必须枚举每一个点跑一次dfs
    • 为了避免出现通向环的情况,必须加上标志,在每次dfs时候,标记非0值表示访问过,但是进入下一层dfs时,标记为-1,如果下层dfs访问到这个节点时的标记为-1,说明有环,出来dfs才设置为1,表示这个点后面没有同向环

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

const int maxn = 100 + 10;

//n表示节点数,m表示边数,g保存有向边的信息,vis保存是否访问过节点,t表示当前拓扑排序的编号,topo保存拓扑排序的结果

//注意,这里节点的编号是 1 ~ n 

int n,m,g[maxn][maxn],vis[maxn],topo[maxn],t;

int dfs(int u){

        vis[u] = -1;

        for(int v = 1,;v < n + 1;v++){

                if(g[u][v]){

                        if(vis[v] < 0)  return 0;

                        if(!vis[v] && !dfs(v))  return 0;

                }

        }

        vis[u] = 1;

        topo[--t] = u;

        return 1;

}

int toposort(){

        t = n;

        memset(vis,0,sizeof(vis));

        //枚举每一个点,如果存在环,就返回0

        for(int u = 1;u < n+1;u++){

                if(!vis[u] && !dfs(u))

                        return 0;

        }

        return 1;

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

const int maxn = 100 + 10;

int n,m,g[maxn][maxn],vis[maxn],topo[maxn],t;

int dfs(int u){

        vis[u] = -1;

        for(int v = 1,;v < n + 1;v++){

                if(g[u][v]){

                        if(vis[v] < 0)  return 0;

                        if(!vis[v] && !dfs(v))  return 0;

                }

        }

        vis[u] = 1;

        topo[--t] = u;

        return 1;

}

int toposort(){

        t = n;

        memset(vis,0,sizeof(vis));

        for(int u = 1;u < n+1;u++){

                if(!vis[u] && !dfs(u))

                        return 0;

        }

        return 1;

}

来自为知笔记(Wiz)

时间: 2024-11-09 14:29:30

[2016-02-18][拓扑排序]的相关文章

拓扑排序之变量序列代码

/* Name: Copyright: Author: Date: 17-11-14 21:02 Description: 拓扑排序之变量序列 假设有n个变量(1<=n<=26,变量名用单个小写字母表示),还有m个二元组(u,v),分别表示变量u小于v.那么,所有变量从小到大排列起来应该是什么样子的呢? 例如有4个变量a,b,c,d,若以知a<b,c<b,d<c,则这4个变量的排序可能是a<d<c<b.尽管还有可能其他的可能,你只需找出其中的一个即可. In

分布式技术一周技术动态 2016.02.21

分布式系统实践 1. 远程接口设计经验分享 http://mp.weixin.qq.com/s?__biz=MzAwNjQwNzU2NQ%3D%3D&idx=2&mid=402064901&scene=0&sn=0b5f56a97b431ed355b75a9e17f2e754 要点: 分布式系统由于中间存在网络因素, 出错的情况比单机系统要多很多, 那么如何设计一个远程接口呢? 本文很好的解释了设计远程接口需要考虑的问题点. 2. 时序列数据库武斗大会之什么是TSDB ht

拓扑排序之关键路径(深度优先搜索)

/* Name: 拓扑排序之关键路径(深度优先搜索) Copyright: Author: 巧若拙 Date: 17-11-14 21:02 Description: 拓扑排序之关键路径 若在带权的有向图中,以顶点表示事件,以有向边表示活动,边上的权值表示活动的开销(如该活动持续时间), 则此带权的有向图称为边表示活动的网 (Activity on Edge Network) ,简称 AOE 网. (1)AOV 网具有的性质 ⒈ 只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动

模板:拓扑排序

原理: 1.从DAG图中选一个 没有前驱(即入度为0)的顶点并输出2.从图中删除该顶点和所有以它为起点的有向边3.重复1和2直到当前的DAG为空或当前图中不存在无前驱的顶点为止,后一种情况说明有向图中一定有环. 1 int n; 2 int in[N]; 3 bool E[N][N]; 4 queue <int> Q; 5 6 void toposort(){ 7 for(int i=1;i<=n;i++){ 8 //寻找入度为0的点 9 int j=1; 10 while(in[j]!

CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序

题目链接:http://codeforces.com/contest/655/problem/D 大意是给若干对偏序,问最少需要前多少对关系,可以确定所有的大小关系. 解法是二分答案,利用拓扑排序看是否所有关系被唯一确定.即任意一次只能有1个元素入度为0入队. 1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <string> 5 #include <

2016&quot;百度之星&quot; - 初赛(Astar Round2A)1006 Gym Class(HDU5695)——贪心+拓扑排序

分析:首先,利用贪心可知,如果要所有人的分数和最高,需要把序号大的优先放在前面.其次,对于a的前面不能为b,那么只能a在b前面了,那么就建立一条从a到b的边,并且b的入度加1.然后就是拓扑排序了.要分数最高,则把哪些入度为0的点(他们不需要有哪些人一定要在他们前面,最自由)丢进优先队列,然后就可以实现把序号大的尽量放在前面而且满足题意了. 具体见代码: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string

2016&quot;百度之星&quot; - 初赛(Astar Round2A)Gym Class(拓扑排序)

Gym Class Accepts: 849 Submissions: 4247 Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 众所周知,度度熊喜欢各类体育活动. 今天,它终于当上了梦寐以求的体育课老师.第一次课上,它发现一个有趣的事情.在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到NN,在排好队之后,每个同学会找

CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 拓扑排序+二分

题目链接: http://www.codeforces.com/contest/655/problem/D 题意: 题目是要求前k个场次就能确定唯一的拓扑序,求满足条件的最小k. 题解: 二分k的取值,做拓扑排序的时候只要每次只有一个元素没有前驱就可以唯一了. #include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> #includ

拓扑排序(Topological Order)UVa10305 Ordering Tasks

2016/5/19 17:39:07 拓扑排序,是对有向无环图(Directed Acylic Graph , DAG )进行的一种操作,这种操作是将DAG中的所有顶点排成一个线性序列,使得图中的任意一对顶点u,v满足如下条件: 若边(u,v)∈E(G),则在最终的线性序列中出现在v的前面 好了,说人话:拓扑排序的应用常常和AOV网相联系,在一个大型的工程中,某些项目不是独立于其他项目的,这意味着这种非独立的项目的完成必须依赖与其它项目的完成而完成,不妨记为u,v,则若边(u,v)∈E(G),代

CSU 1804: 有向无环图(拓扑排序)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在这个时候对答案的贡献就是∑(a1 + a2 + a3 + ... + ai) * bv,其中a是之前遍历到的点,v是当前遍历的点. 这样想之后就很简单了.类似于前缀和,每次遍历到一个v点,就把a[u]加给a[v],然后像平时的拓扑排序做就行了. 1 #include <bits/stdc++.h>