码迷,mamicode.com
首页 > 其他好文 > 详细

2018.2.2

时间:2018-02-03 12:32:19      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:就是   开始   connected   随机   bfs   头结点   思路   路径   connect   

重回algo。

广度优先算法(BFS)。这个算法会用到队列的数据结构,简单说就是先进队列的结点最后会先出来,后进的后出。队列里最开始只有初始结点,让结点出队,然后分析每个这个结点能够连到的结点,如果目标结点没有被探索过(这里需要一个标记),标记它为已探索,然后让他入队,之后对每个入队的结点都对相同的处理。直到队列变为空队列,就意味着所有能够搜到的结点都搜完了。

这个算法是O(m+n)的。并且如果在做这个算法的时候多加一个标记,就可以顺便用来算其他所有结点相比于初始结点的最小路径。简单说就是初始结点的标记为0,那么从初始结点搜到的结点标记就为1,每搜到的新结点标记相比头结点加1。

当然还有深度优先算法(DFS)。深度有限算法是一个递归算法。它把所有结点分成两种状态:已完结和未完结。从初始结点出发搜下一个点,如果没有点可搜,标记该点为已完结并返回它的头结点,如果有点可搜,那么如果是已发现的就无视它,如果未发现,就对该点递归该算法。

同样它也是O(m+n)的。这个算法可以用来给有向图做拓扑排序。

拓扑排序就是把有向图的结点做成人体蜈蚣形状的(喂)。一个显而易见的思路就是找一个没有出边的结点,如果找不到就说明有向图有内循环,做不了拓扑排序,能找到的话,就删掉这个结点和与它相连的边,然后对剩余的有向图递归该算法。

不过实际上也很显然,在DFS的时候顺便加一个标记就可以顺手解决拓扑排序问题了。只需要把结点的完结顺序记录下来,然后一字排开就好了。

DFS还有一个应用就是寻找 strongly connected components (SCC),SCC就是一堆结点的集合,在这集合里面每个结点之间都能互通。一般来说可以把一个巨型图拆解为不同的SCC的集合。 寻找SCC的kosaraju算法基本流程就是把有向图的方向倒过来,对这个反向图做一次DFS,初始点可以随机的,把结点的完结顺序纪录下来。之后对正向图再做一次DFS,不过这里初始点就不能乱选了,要选之前那次DFS中最晚完结的点,以它开始做DFS,当它结束时,此时已完结的结点集合就构成了一个SCC。之后找到新的(此次DFS还没完结的)最晚完结的点,继续此次DFS,后面的流程类似,到最后所有点都完结的时候就得到了多个SCC了。

kosaraju算法的证明吧。。。抱歉我又没看懂。。。这里面SCC之间临界结点的部分是比较tricky的,我听的云里雾里。不过很显然它也是O(m+n)的。后面光头哥讲了一个SCC的直接应用,就是互联网网页之间的有向图关系,还蛮有趣的。

 

2018.2.2

标签:就是   开始   connected   随机   bfs   头结点   思路   路径   connect   

原文地址:https://www.cnblogs.com/dynasty919/p/8408556.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!