模板:拓扑排序

原理:

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]!=0) j++;
11         in[j]--;
12         Q.push(j);
13         //将关联的点的入度减1,即删除与该节点关联的边
14         for(int k=1;k<=n;k++){
15             if(E[j][k]) in[k]--;
16         }
17     }
18 }

拓扑排序判环:

 1 //n^2判环
 2
 3 int n;
 4 const int N=5e2+10;
 5 int E[N][N],vis[N];//vis[i]=0,-1,1分别表示未访问、正在访问、已访问并且已递归访问完所有子孙
 6
 7 bool dfs(int u){
 8     vis[u]=-1;
 9     for(int i=1;i<=n;i++){
10         if(E[u][i]){
11             if(vis[i]<0) return false;
12             else if(!vis[i]&&!dfs(i)) return false;
13         }
14     }
15     vis[u]=1;
16     ans.push(u);
17     return true;
18 }
19
20 bool toposort(){
21     memset(vis,0,sizeof(vis));
22     for(int i=1;i<=n;i++){
23         if(!vis[i]){
24             if(!dfs(i)) return false;
25         }
26     }
27     return true;
28 }

原文地址:https://www.cnblogs.com/Leonard-/p/8455296.html

时间: 2024-10-18 02:31:04

模板:拓扑排序的相关文章

拓扑排序 --- 模板题

确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10536    Accepted Submission(s): 4120 Problem Description 有 N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排 名,但现在裁判委员会不能

拓扑排序模板

拓扑排序是对ADG(有向无环图进行线性排序) 模板: 队列实现 #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; int indegree[100]; queue<int> q; int n,m; bool map[100][100]; int a[100]; int topo(int n) { int cnt =

HDU-1285-确定比赛名次-拓扑排序(模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 这是一道拓扑排序的模板题,用来学拓扑排序很好.我的算法62ms过的,效率还是很低,不过很好理解:用一个结构体记录每个点的入度出度就搞定了: #include<iostream> #include<string> #include<cstdio> #include<cstring> #include<queue> #include<map&

HDU 1285 确定比赛名次(拓扑排序模板)

题意还是比较容易理解的,关键要看到后面的:合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前: 思路:这道题就是拓扑排序的经典应用了,用队列做的考虑优先编号小的出队就可以了. 拓扑排序: 拓扑排序是对有向无回路图(DAG)顶点的一种排序,它使得如果存在从u到v的有向路径,那么满足序列中u在v前. 所以我们的算法可以描述为这样一个过程: 1.找到整个图中所有的度为0的点,将这些点压进队列(栈)中 2.从队列(栈)中取出一点,输出,将该点及它的边删除,找到它所指向的点,如果改点是一个原点(删

拓扑排序,树的直径模板(CF14D 枚举删边)

HDU4607 树的直径 #include <stdio.h> #include <string.h> #include <iostream> #include <queue> #include <vector> using namespace std; #define N 100005 #define INF 1<<30 int n,dis[N],E; bool vis[N]; vector<int>G[N]; //注意

拓扑排序【模板】

1.普通判断拓扑排序.输出路径:queue<int> Q 2.满足字典序的拓扑排序:priority_queue<int,vector<int>, greater<int> > Q; 保证了权值小的优先级高,取出的时候保证序号是队列中最小的. 3.满足最小的尽量在前面(不保证是字典序):priority_queue<int> Q; 反向建图,用优先队列存储将入度为0的点,再遍历权值大的结点,从大到小存入数组ans[],最后ans[]逆序就是满足要

hdu 2647 (拓扑排序 邻接表建图的模板) Reward

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2647 老板给员工发工资,每个人的基本工资都是888,然后还有奖金,然后员工之间有矛盾,有的员工希望比某员工的奖金多,老板满足了所以员工的这种心思,而且老板下午发的总工资最少,问最少是多少?比如 a b 表示a的工资比b要高(高一块钱),当出现a b   b c   c a这种环的时候输出-1 拓扑排序http://www.cnblogs.com/tonghao/p/4721072.html 小指向大

拓扑排序(待更新模板)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593

转:【拓扑排序详解】+【模板】

转自:http://www.cnblogs.com/skywang12345/p/3711489.html 拓扑排序介绍 拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列. 这样说,可能理解起来比较抽象.下面通过简单的例子进行说明! 例如,一个项目包括A.B.C.D四个子部分来完成,并且A依赖于B和D,C依赖于D.现在要制定一个计划,写出A.B.C.D的执行顺序.这时,就可以利用到拓扑

[模板]tarjan缩点+拓扑排序

题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先tarjan缩点,再从入度为零处进行一次拓扑排序,求最长路即可,话说拓扑排序求最长路真方便... 注意: 要明确拓扑的写法,要用栈写最优. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define man 100010 4 inline i