拓扑排序(基于dfs+基于队列)
经典问题-Ordering Tasks
dfs函数的返回值表示是否成环,若存在有向环,则不存在拓扑排序。不包含有向环的有向图称为有向无环图(DAG)
可以借助DFS完成拓扑排序,在访问完一个结点时把他加入当前拓扑序的首部。
举个栗子:比如一个(1,2),(1,3),(2,3)的有向无环图,就先搜索1,再递归搜索2,再搜索3,3没有出度了,于是放进拓扑序尾=,再回到2,2除3外没有出度,再放入拓扑序,再回到1,1除2,3没有出度,放入拓扑序
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <set>
#include <vector>
#include <cctype>
#include <iomanip>
#include <sstream>
#include <climits>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
#define INF 0X3f3f3f3f
const ll MAXN = 1e3 + ;
const ll MOD = 1e9 + ;
int mp[MAXN][MAXN];
int vis[MAXN];
int topo[MAXN], t;//topo数组存放最后拓扑排序结果
int n,k,m;
bool dfs(int u)//判环
{
vis[u] = -; //访问标志
for(int i=;i<=n;i++)
{
if(mp[u][i])
{
if(vis[i]==-) return false;//存在有向环,退出
if(!vis[i]&&!dfs(i)) return false;
}
}
topo[--k]=u;
vis[u]=;
return true;
}
bool toposort()
{
memset(vis,,sizeof(vis));
k=n;
for(int i=;i<=n;i++)
if(!vis[i]&&!dfs(i)) return false;
return true;
}
void print()
{
for(int i=;i<n;i++)
{
if(i) cout<<' ';
cout<<topo[i];
}
cout<<endl;
return ;
}
int main()
{
ios::sync_with_stdio(false);
while (cin >> n >> m&&(n|m))
{
memset(mp,,sizeof(mp));
for (int i = ; i < m; i++)
{
int a,b;
cin>>a>>b;
mp[a][b]=;
}
if(toposort())
print();
else
cout<<"sorry to say there is no DAG"<<endl;//跟题目并没有关系...
}
return ;
}
加个队列写法..
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <set>
#include <vector>
#include <cctype>
#include <iomanip>
#include <sstream>
#include <climits>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
#define INF 0X3f3f3f3f
const ll MAXN = 1e3 + ;
const ll MOD = 1e9 + ;
int n, m;
int degree[MAXN][MAXN];
int indegree[MAXN];
int topo[MAXN];
void toposort()
{
int cnt = ;
queue<int> que;
for (int i = ; i <= n; i++)
if (!indegree[i])
que.push(i);
int cur;
while (!que.empty())
{
cur = que.front();
que.pop();
topo[cnt++] = cur;
for (int i = ; i <= n; i++)
{
if (degree[cur][i])
{
indegree[i]--;
if (!indegree[i])
que.push(i);
}
}
}
return;
}
void print()
{
for (int i = ; i < n; i++)
{
if (i)
cout << ' ';
cout << topo[i];
}
cout << endl;
return;
}
int main()
{
ios::sync_with_stdio(false);
while (cin >> n >> m && (n | m))
{
memset(degree, , sizeof(degree));
memset(indegree, , sizeof(indegree));
while (m--)
{
int a, b;
cin >> a >> b;
if (!degree[a][b])
{
degree[a][b] = ;
indegree[b]++;
}//处理重边
}
toposort();
print();
}
return ;
}
拓扑排序(基于dfs+基于队列)的更多相关文章
- POJ 1270 Following Orders (拓扑排序,dfs枚举)
题意:每组数据给出两行,第一行给出变量,第二行给出约束关系,每个约束包含两个变量x,y,表示x<y. 要求:当x<y时,x排在y前面.让你输出所有满足该约束的有序集. 思路:用拓扑排 ...
- Uva 10305 - Ordering Tasks 拓扑排序基础水题 队列和dfs实现
今天刚学的拓扑排序,大概搞懂后发现这题是赤裸裸的水题. 于是按自己想法敲了一遍,用queue做的,也就是Kahn算法,复杂度o(V+E),调完交上去,WA了... 于是检查了一遍又交了一发,还是WA. ...
- 【紫书】Ordering Tasks UVA - 10305 拓扑排序:dfs到底再输出。
题意:给你一些任务1~n,给你m个数对(u,v)代表做完u才能做v 让你给出一个做完这些任务的合理顺序. 题解:拓扑排序版题 dfs到底再压入栈. #define _CRT_SECURE_NO_WAR ...
- ZOJ 4124 拓扑排序+思维dfs
ZOJ - 4124Median 题目大意:有n个元素,给出m对a>b的关系,问哪个元素可能是第(n+1)/2个元素,可能的元素位置相应输出1,反之输出0 省赛都过去两周了,现在才补这题,这题感 ...
- Toposort(拓扑排序)dfs递归模板
最近刷了几题拓扑排序的题,记录一下拓扑排序 在有向图中,并且按照一定的规则(题目所给的规则)排序.如果图中出现了有向环的话就无法排序了. int gap[maxn][maxn];//记录下有向边 in ...
- 拓扑排序(dfs)
int c[N];//c[u]=0表示从来没有访问过:c[u]=1表示已经访问过,并且还递归访问过它的所有子:c[u]=-1表示正在访问. int topo[N],t; int G[N][N]; bo ...
- HDU 2647 Reward 【拓扑排序反向建图+队列】
题目 Reward Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to d ...
- 拓扑排序-DFS
拓扑排序的DFS算法 输入:一个有向图 输出:顶点的拓扑序列 具体流程: (1) 调用DFS算法计算每一个顶点v的遍历完成时间f[v] (2) 当一个顶点完成遍历时,将该顶点放到一个链表的最前面 (3 ...
- 集训队8月1日(拓扑排序+DFS+主席树入门)
上午看书总结 今天上午我看了拓扑排序,DFS+剪枝,相当于回顾了一下,写了三个比较好的例题.算法竞赛指南93~109页. 1.状态压缩+拓扑排序 https://www.cnblogs.com/246 ...
随机推荐
- linux中的文件类型标记方法
在ls -l显示的详细信息中有以下信息: -rw-r--r-- drwxr-xr-x 一共10个字符,第一个字符表示文件类型,后面9个字符分成3组表示文件权限.前三个表示属主(拥有者)对文件的权限,中 ...
- Perl 的内置变量$|
$|是perl的内置变量,默认情况下是0,如果设置为非0的话,表示当前的输出不经过缓存立刻输出.相当于c语言的fflush()函数,立即刷新缓冲区. 比如你print或者write一个文件,实际是需要 ...
- TestStand 界面重置【小技巧】
有几种情况可能会使用到这个功能: (1)当界面调整的很乱的时候 (2)当界面突然消失的时候(但是软件进程还在)--快捷键 Alt+V 会弹出菜单,再点击Reset UI Configuration即可 ...
- python入门之字符串的魔法
1.test="alex" v=test.capitalize() print(v) //输出结果首字母大写 2.test1="alex&qu ...
- jquery中获取当前选中行数据的方法
$("table tr").click(function() { var td = $(this).find("td");// 找到td元素 var lo_id ...
- 【转载】你未必知道的49个CSS知识点
原文链接: https://juejin.im/post/5d3eca78e51d4561cb5dde12 虽然大多数我都会,嘻嘻.不过案例太生动了,值得收藏.
- 洛谷$P$1402 酒店之王 网络流
正解:网络流 解题报告: 传送门! 一看就很网络流昂,,,于是现在的问题就变成怎么建图了$QwQ$ 首先如果只有一个要求,那就直接按要求建图然后跑个最大流就好. 现在变成,有两个要求,必须同时满足,考 ...
- SpringBoor与SpringCloud的关系
SpringBoot是一个快速开发的框架,能够快速的整合第三方框架.简化XML配置,全部采用注解形式,内置Web服务器(如Tomcat等),帮助开发者能够实现快速开发,SpringBoot Web控制 ...
- 调试排错 - Java问题排查:Linux命令
本文原创,更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. Java 在线问题排查主要分两篇:本文是第一篇,通过linux常用命令排查.@pdai 文本操作 文本查找 - grep g ...
- 小小知识点(十七)——对数形式功率(dBm)与非对数形式功率(w)之间的换算关系
摘自https://blog.csdn.net/shij19/article/details/52946454 dBm 物理含义是:一个表示功率绝对值的值(也可以认为是以1mW功率为基准的一个比值) ...