http://www.lintcode.com/zh-cn/problem/topological-sorting/#

给定一个有向图,图节点的拓扑排序被定义为:

  • 对于每条有向边A--> B,则A必须排在B之前
  • 拓扑排序的第一个节点可以是任何在图中没有其他节点指向它的节点

找到给定图的任一拓扑排序

solution

Topological Sorting

Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every directed edge uv, vertex u comes before v in the ordering. Topological Sorting for a graph is not possible if the graph is not a DAG.

For example, a topological sorting of the following graph is “5 4 2 3 1 0″. There can be more than one topological sorting for a graph. For example, another topological sorting of the following graph is “4 5 2 3 1 0″. The first vertex in topological sorting is always a vertex with in-degree as 0 (a vertex with no in-coming edges).

Topological Sorting vs Depth First Traversal (DFS):
In DFS, we print a vertex and then recursively call DFS for its adjacent vertices. In topological sorting, we need to print a vertex before its adjacent vertices. For example, in the given graph, the vertex ‘5’ should be printed before vertex ‘0’, but unlike DFS, the vertex ‘4’ should also be printed before vertex ‘0’. So Topological sorting is different from DFS. For example, a DFS of the above graph is “5 2 3 1 0 4″, but it is not a topological sorting

Algorithm to find Topological Sorting:
We recommend to first see implementation of DFS here. We can modify DFSto find Topological Sorting of a graph. In DFS, we start from a vertex, we first print it and then recursively call DFS for its adjacent vertices. In topological sorting, we use a temporary stack. We don’t print the vertex immediately, we first recursively call topological sorting for all its adjacent vertices, then push it to a stack. Finally, print contents of stack. Note that a vertex is pushed to stack only when all of its adjacent vertices (and their adjacent vertices and so on) are already in stack.

引用自 http://www.geeksforgeeks.org/topological-sorting/

如果仅仅只是对DAG进行DFS,那么针对某一起始点(例如上图中的5)开始的DFS确实可以满足Topological sorting,但是当对该点DFS范围以外的其他点(例如上图中的4)再进行DFS时,很可能会出现不满足Topological sorting的情况。例如上图中,在4指向1的清凉下。那如何解决?

利用栈后进先出的性质,我们可以依次递归的将每一个vertex的adjacent vertices先入栈,vertex最后入栈,这样vertices的出栈顺序即满足Topological sorting,代码如下:

// Author: Jian-xin Zhou

/**
* Definition for Directed graph.
* struct DirectedGraphNode {
* int label;
* vector<DirectedGraphNode *> neighbors;
* DirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
/**
* @param graph: A list of Directed graph node
* @return: Any topological order for the given graph.
*/
vector<DirectedGraphNode*> topSort(vector<DirectedGraphNode*> graph) {
// write your code here
unordered_set<DirectedGraphNode*> unique;
stack<DirectedGraphNode*> st;
topologicalSort(graph, unique, st); vector<DirectedGraphNode*> ret;
while (!st.empty()) {
ret.push_back(st.top());
st.pop();
} return ret;
} private:
void topologicalSortUtil(DirectedGraphNode *node,
unordered_set<DirectedGraphNode*> &unique,
stack<DirectedGraphNode*> &st) {
// 处理 neighbors
for (const auto &nodePointer : node->neighbors) {
if (unique.count(nodePointer) == 0) {
unique.insert(nodePointer);
topologicalSortUtil(nodePointer, unique, st);
}
} // 处理完 neighbors ,自身入栈
st.push(node);
} void topologicalSort(vector<DirectedGraphNode*> graph,
unordered_set<DirectedGraphNode*> &unique,
stack<DirectedGraphNode*> &st) {
for (const auto &node : graph) {
if (unique.count(node) == 0) {
unique.insert(node);
topologicalSortUtil(node, unique, st);
}
}
}
};

[LintCode] 拓扑排序的更多相关文章

  1. BFS (1)算法模板 看是否需要分层 (2)拓扑排序——检测编译时的循环依赖 制定有依赖关系的任务的执行顺序 djkstra无非是将bfs模板中的deque修改为heapq

    BFS模板,记住这5个: (1)针对树的BFS 1.1 无需分层遍历 from collections import deque def levelOrderTree(root): if not ro ...

  2. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  3. 有向无环图的应用—AOV网 和 拓扑排序

    有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...

  4. 【BZOJ-2938】病毒 Trie图 + 拓扑排序

    2938: [Poi2000]病毒 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 609  Solved: 318[Submit][Status][Di ...

  5. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  6. 图——拓扑排序(uva10305)

    John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task i ...

  7. Java排序算法——拓扑排序

    package graph; import java.util.LinkedList; import java.util.Queue; import thinkinjava.net.mindview. ...

  8. poj 3687(拓扑排序)

    http://poj.org/problem?id=3687 题意:有一些球他们都有各自的重量,而且每个球的重量都不相同,现在,要给这些球贴标签.如果这些球没有限定条件说是哪个比哪个轻的话,那么默认的 ...

  9. 拓扑排序 - 并查集 - Rank of Tetris

    Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球 ...

随机推荐

  1. Ubuntu 双网卡设置

    闲话不多说,直接正题 因为chinanet信号不强,所以买了个usb无线网卡,平常又要做开发,要连着开发板,不知怎么回事,一旦自带无线网卡连上内网的无线路由,就不能访问外网了. 网上搜了好久,终于查到 ...

  2. [linux]Linux如何查看文件中的中间部分内容

    最基本的是cat.more和less. 1. 如果你只想看文件的前5行,可以使用head命令,如: head -5 /etc/passwd 2. 如果你想查看文件的后10行,可以使用tail命令,如: ...

  3. strace使用

    统计信息 -c -- count time, calls, and errors for each syscall and report summary 输出结果到文件 -o   例如 strace ...

  4. spring security 4.2后出现CouldnotverifytheprovidedCSRFtokenbecauseyoursessionwasnotfound

    升级到spring security 4.2后,登录不了,出现下面的错误 WARN DefaultHandlerExceptionResolver:361 - Failed to bind reque ...

  5. bootstrap css布局

    1.移动先行 <meta name="viewport" content="width=device-width, initial-scale=1, maximum ...

  6. Python多进程并发操作进程池Pool

    目录: multiprocessing模块 Pool类 apply apply_async map close terminate join 进程实例 multiprocessing模块 如果你打算编 ...

  7. 透过摩拜和ofo,看产品从0到1时如何取舍需求(转)

    大纲 背景介绍 从0至1,我们成功的关键是什么? 从0到1,我们为什么选择做?又为什么选择不做? 从0到1,我们面临什么选择?我们作出了什么选择? 从0到1,我们为什么作出了这种选择? 背景 在资本注 ...

  8. spring boot 实现mybatis拦截器

    spring boot 实现mybatis拦截器 项目是个报表系统,服务端是简单的Java web架构,直接在请求参数里面加了个query id参数,就是mybatis mapper的query id ...

  9. from __future__ import

    读代码的过程中看到的,好奇搜索了一下,其实当在我们调试别人Python代码的过程中经常会遇到一些问题,比如版本不同,代码也会有所改变,比如print函数 Python 2.7版本为 print “ ” ...

  10. Java 学习之集合类(Collections)

    Collection(集合类) 我们是使用数组来保存数据,但是他的长度一旦创建,就已经确定了,当我们要动态传入穿值,数组就有些局限了,集合类就孕育而生:所谓集合,就是来保存,盛装数据,也可称为容器类: ...