经典问题-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 ;
}

最新文章

  1. cygwin 安装apt-cyg命令
  2. 【转】TextView长按复制实现方法小结
  3. 数学+dp HDOJ 5317 RGCDQ
  4. html5 app开发重大消息-腾讯在技术端推进Html5生态发展
  5. wifi配置常用命令总结
  6. 重新开始学习javase_Exception
  7. C++11之后,对源代码增加了UTF8和UCS4的支持(Windows内部使用Unicode,因为nt内核用的是ucs2,那是89年,utf8到了92年才发明出来)
  8. linux性能优化常用命令
  9. css3的滤镜模糊的效果
  10. 《团队作业第二周》五小福团队作业——UNO
  11. php的array数组 -------方法array_column()
  12. 玩转物联网之MQTT
  13. ubuntu下修改网卡名称
  14. [Spring-AOP-XML] 利用Spirng中的AOP和XML进行事务管理
  15. ZooKeeper在分布式应用中的作用
  16. Spark2 Dataset行列操作和执行计划
  17. 【BZOJ4025】二分图(线段树分治,并查集)
  18. 跨域ajax请求携带cookie
  19. IT人应当知道的10个行业小内幕
  20. leetcode 74 搜索二维矩阵 java

热门文章

  1. 【题解】有标号的DAG计数3
  2. Synchronized解析——如果你愿意一层一层剥开我的心
  3. Python 官方团队在打包项目中踩过的坑
  4. DNS服务器红帽5.4搭建图文教程!!!
  5. 1072 开学寄语 (20分)C语言
  6. 【一起学源码-微服务】Ribbon 源码三:Ribbon与Eureka整合原理分析
  7. Win10系统下应用窗口任务栏居中效果
  8. json查询结果绑定
  9. C语言之枚举数据类型
  10. Ambari下安装oozieUI界面无法访问问题