拓扑排序(基于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 ...
随机推荐
- 49.植入HTML和自定义元件库
首先设置一个圆角矩形 设置鼠标单击时的k空用例 这样当鼠标单击时会有一个小手的图标 然后设置鼠标移入时的动作 鼠标移入时设置文本动作的文本
- 【题解】Comet OJ Round 70 简要题解
[题解]Comet OJ Round 70 简要题解 A 将放在地上的书按照从小到大排序后,问题的本质就变成了合并两个序列使得字典序最小.可以直接模拟归并排序.直接用循环和std::merge实现这个 ...
- Python 打包——过去、现在与未来
英文 | Python packaging - Past, Present, Future[1] 原作 | BERNAT GABOR 译者 | 豌豆花下猫 声明 :本文获得原作者授权翻译,转载请保留原 ...
- 电信NBIOT平台的CA证书上传-消息订阅回调地址检测503错误
在NBIOT北向开发过程中,遇到消息订阅回调地址检测503错误,经过论坛查询与文档查阅一直都没有解决问题,大多人都说是RESTful地址格式问题,但其实不是.最终发现是我们在电信平台创建应用时,上传C ...
- 基于CentOS 7 部署MySQL 5.7的基本操作
关闭selinux # sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config重启后生效# sestatus 修改提示符配置# vi / ...
- Java面向对象之异常详解
目录 Java面向对象之异常[一] Java面向对象之异常[二] 捕获异常的规则 访问异常信息 异常对方法重写的影响 finally详解 Java面向对象之异常[一] Java面向对象之异常[二] 往 ...
- Spring中使用注解 @Scheduled执行定时任务
注解@Scheduled 使用方式 注解@Scheduled 可以作为一个触发源添加到一个方法中,例如,以下的方法将以一个固定延迟时间5秒钟调用一次执行,这个周期是以上一个调用任务的完成时间为基准,在 ...
- Lua表(table)的个人总结
1.表的简介和构造 table是个很强大且神奇的东西,又可以作为数组和字典,又可以当作对象,设置module.它是由数组和哈希表结合的实现的.他的key可以是除nil以外任意类型的值,key为整数时, ...
- swiper如何禁止左右箭头切换
swiper做项目时,需求 带着左右两边的箭头, 场景1:swiper自动切换,此时左右箭头点击时不能切换 场景2:swiper手动切换,左右箭头可以实现切换,通过翻阅api 终于找到 <s ...
- windows I/O设备
当外部设备连接到windows后,设备所连接到的集线器驱动程序将为设备分配硬件ID,然后Windows 使用硬件 Id 查找设备与包含设备驱动程序的驱动程序包之间最近的匹配项. 如果查找到,设备就可以 ...