图的DFS。。类似树的DFS

Depth-First Search (DFS)

Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data structures. One starts at the root (selecting some arbitrary node as the root in the case of a graph) and explores as far as possible along each branch before backtracking.

判断连通性代码:

const allowTraversalCallback = (
    () => {
      const seen = {};
      return ({ nextVertex }) => {//如果没有访问过邻近结点,则返回true
        if (!seen[nextVertex.getKey()]) {
          seen[nextVertex.getKey()] = true;
          return true;
        }
        return false;
      };
    }
  )();

完整代码:

/**
 * @typedef {Object} Callbacks
 *
 * @property {function(vertices: Object): boolean} [allowTraversal] -
 *  Determines whether DFS should traverse from the vertex to its neighbor
 *  (along the edge). By default prohibits visiting the same vertex again.
 *
 * @property {function(vertices: Object)} [enterVertex] - Called when DFS enters the vertex.
 *
 * @property {function(vertices: Object)} [leaveVertex] - Called when DFS leaves the vertex.
 */

/**
 * @param {Callbacks} [callbacks]
 * @returns {Callbacks}
 */
function initCallbacks(callbacks = {}) {//对回调函数进行初始化
  const initiatedCallback = callbacks;

  const stubCallback = () => {};

  const allowTraversalCallback = (
    () => {
      const seen = {};
      return ({ nextVertex }) => {//如果没有访问过邻近结点,则返回true
        if (!seen[nextVertex.getKey()]) {
          seen[nextVertex.getKey()] = true;
          return true;
        }
        return false;
      };
    }
  )();

  initiatedCallback.allowTraversal = callbacks.allowTraversal || allowTraversalCallback;
  initiatedCallback.enterVertex = callbacks.enterVertex || stubCallback;
  initiatedCallback.leaveVertex = callbacks.leaveVertex || stubCallback;

  return initiatedCallback;
}

/**
 * @param {Graph} graph
 * @param {GraphVertex} currentVertex
 * @param {GraphVertex} previousVertex
 * @param {Callbacks} callbacks
 */
function depthFirstSearchRecursive(graph, currentVertex, previousVertex, callbacks) {
  callbacks.enterVertex({ currentVertex, previousVertex });

  graph.getNeighbors(currentVertex).forEach((nextVertex) => {
    if (callbacks.allowTraversal({ previousVertex, currentVertex, nextVertex })) {
      depthFirstSearchRecursive(graph, nextVertex, currentVertex, callbacks);
    }
  });

  callbacks.leaveVertex({ currentVertex, previousVertex });
}

/**
 * @param {Graph} graph
 * @param {GraphVertex} startVertex
 * @param {Callbacks} [callbacks]
 */
export default function depthFirstSearch(graph, startVertex, callbacks) {
  const previousVertex = null;
  depthFirstSearchRecursive(graph, startVertex, previousVertex, initCallbacks(callbacks));
}

原文地址:https://www.cnblogs.com/Archer-Fang/p/10529551.html

时间: 2024-10-11 08:17:08

图的DFS。。类似树的DFS的相关文章

HDU 5296 Annoying problem(LCA模板+树的dfs序心得)

Problem Description Coco has a tree, whose nodes are conveniently labeled by 1,2,-,n, which has n-1 edge,each edge has a weight. An existing set S is initially empty. Now there are two kinds of operation: 1 x: If the node x is not in the set S, add n

【bzoj2819】Nim DFS序+树状数组+倍增LCA

题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略的.于是vfleaking决定写一个玩Nim游戏的平台来坑玩家.为了设计漂亮一点的初始局面,vfleaking用以下方式来找灵感:拿出很多石子,把它们聚成一堆一堆的,对每一堆编号1,2,3,4,...n,在堆与堆间连边,没有自环与重边,从任意堆到任意堆都只有唯一一条路径可到达.然后他不停地进行如下操

poj3321-Apple Tree(DFS序+树状数组)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36442   Accepted: 10894 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has bee

DFS序-树链剖序-欧拉序

,二叉树是一颗线段树,树状数组,树上的每个维护节点负责维护一个区间信息,节点之间又包含和属于的关系.例如线段树: DFS序: 我们通过对每个节点设置两个量,in和out.从根节点开始DFS搜索,in为第一次搜索到时的时间戳,out为退出出栈时的时间戳. 可以得到,例如我们要查询以b为根节点我们只需要查询区间[2,5]:要查询以c为根节点子树的信息,我们可以查询区间[6,7]:查询a需要查询区间[1,8].在程序中,当要查询修改时,我们可以用线段树去维护,因为这些序列的性质和线段树太像了.我们要注

HDU4117 GRE WORDS(AC自动机+线段树维护fail树的dfs序)

Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the most important thing is reciting the words. Now George is working on a word list containing N words. He has so poor a memory that it is too hard for him

【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高速光缆组成.每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络.该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信. 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略.但是由于路由器老化,在这些

POJ 3321:Apple Tree(dfs序+树状数组)

题目大意:对树进行m次操作,有两类操作,一种是改变一个点的权值(将0变为1,1变为0),另一种为查询以x为根节点的子树点权值之和,开始时所有点权值为1. 分析: 对树进行dfs,将树变为序列,记录每个点进栈出栈的时间戳作为其对应区间的左右端点,那么其子节点对应区间必在该区间内,对这段区间求和即可,用树状数组进行修改与求和. 代码: program apple; type point=^node; node=record x:longint; next:point; end; var a:arra

BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状数组维护, DFS到的查询点就回答询问.时间复杂度O(|ACAM|+QlogQ) ------------------------------------------------------------------------------------------- #include<cstdio>

CodeForces 343D 线段树维护dfs序

给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u], 访问结点u的时间戳,out[u],离开结点u的时间戳 每个结点的in值对应在线段树中的区间的一点 那么对于操作1, 只要将区间[in[u],out[u]] 的值都改为1, 但是如果区间[in[u],out[u]] 原先存在为0的点,那么父区间肯定是空的,这个操作不能 改变父区间的状态,所以需要