今天讲的内容是深搜和广搜

  深搜(DFS)

  从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不 了就回退,此种路径搜索策略就称为“深度优先搜索”,简称“深搜”。

  

bool Dfs(V) {
if( V 为终点)
return true;
if( V 为旧点
)
return false;

V标记为旧点
;
对和
V相邻的每个节点U {
if( Dfs(U) == true)
return true;
}
return false;
}
int main()
{
将所有点都标记为新点;
起点 =
终点 =
cout << Dfs(起点);
}

判断从 V出发是否能走到终点:

  用的时候注意剪枝:最优性剪枝 和 可行性剪枝

  用深搜找最优路径时用最优性剪枝:搜索过程中总长度大于或等于之前所求得的最优解则剪掉。

  另一种通用的最优性剪枝思想 ---保存中间计算结果用于最优性剪枝(用空间换时间)

  可行性剪枝是先判断出这个条件下是否可行,不可行则直接返回。

  两种剪枝可以一起使用。

  运用剪枝时复杂度不好估计

  搜索顺序 : 一个事若由多个无关步骤组成,应先尝试选择少的 ,选择少的正确率高。

ps:用邻接表存图  (可用vector)此时遍历的时间复杂度为 O(n+e)n为节点数目,e为边数目

    若用邻接矩阵遍历的时间复杂度为O(n2

  ps:节省时间的方法:看循环是否能提前break;

例题:1.OpenJ_Bailian 2815 城堡问题

     2.OpenJ_Bailian 4103 踩方格

     3.POJ 1724  ROADS

     4.POJ 1190 生日蛋糕

  广搜(BFS)

  广搜就是一层一层搜。所需要的存储空间较大。一般用队列来存节点。

  要注意初始状态和目标状态。注意判重

  一般状态关系到几个参数判重数组就定义几维。(牵扯到结构体的定义)

  若在你选定的同一状态下会出现不同结果,则考虑的情况少了,需要增加判断参数/维数

  

  若要求输出过程则要记录父节点。

  多组时,为防止时间超限可以采用:

    1.双向广搜(DBFS) :从两个方向以广度优先的顺序同时扩展

    2.预处理 (把所有情况都列出来)

    3.A*算法

例题:1.POJ 3278 Catch That Cow

   2.POJ 3984 迷宫问题

   3.OpenJ_Bailian 4116 拯救行动

   4.OpenJ_Bailian 4115 鸣人和佐助

   5.OpenJ_Bailian 4130 Saving Tang Monk

   6.POJ 1077 Eight

   7.HDU 1043 Eight (多组)

  深搜和广搜的比较:

   1.广搜一般用于状态表示比较简单、求最优策略的问题

     优点:是一种完备策略,即只要问题有解,它就一定可以找到解 。并且,广度优先搜索找到的解,还一定是路径最短的解。

      缺点:盲目性较大,尤其是当目标节点距初始节点较远时,将产生许多无用的节点,因此其搜索效率较低。需要保存所有扩展出的状态,占用的空间大    2.深搜几乎可以用于任何问题

     只需要保存从起始状态到当前状态路径上的节点

   3.根据题目要求凭借自己的经验和对两个搜索的熟练程度做出选择

  双向广度优先搜索(DBFS)

  DBFS算法是对BFS算法的一种扩展。

  BFS算法从起始节点以广度优先的顺序不断扩展,直到遇到目的节点

  DBFS算法从两个方向以广度优先的顺序同时扩展, 一个是从起始节点开始扩展,另一个是从目的节点扩展,直到一个扩展队列中出现另外一个队列中已经扩展的节点,也就相当于两个扩展方向出现了交点,那 么可以认为我们找到了一条路径。

  比较:

    1.DBFS算法相对于BFS算法来说,由于采用了双向扩展的方式,搜索树的宽度得到了明显的减少,时间复杂度和空间复杂度上都有提高!

    2.假设1个结点能扩展出n个结点,单向搜索要m层能找到答案,那 么扩展出来的节点数目就是: (1-n m)/(1-n)

    3.双向广搜,同样是一共扩展m层,假定两边各扩展出m/2层,则总 结点数目 2 * (1-n m/2)/(1-n)

    4.每次扩展结点总是选择结点比较少的那边进行扩展,并不是机械的两边交替。

DBFS的框架:需要两个标志序列,分别记录节点是否出现在两个队列中

void dbfs()
{
. 将起始节点放入队列q0,将目标节点放入队列q1;
. 当两个队列都未空时,作如下循环:
  ) 如果队列q0里的节点比q1中的少,则扩展队列q0;
  ) 否则扩展队列q1
. 如果队列q0未空,不断扩展q0直到为空;
. 如果队列q1未空,不断扩展q1直到为空;
}
int expand(i) //其中i为队列的编号,0或1
{
取队列qi的头结点H;
对H的每一个相邻节点adj:
   如果adj已经在队列qi之中出现过,则抛弃adj;
   如果adj在队列qi中未出现过,则:
    ) 将adj放入队列qi;
    ) 如果adj 曾在队列q1-i中出现过, 则:输出找到的路径
}

ACM北大暑期课培训第三天的更多相关文章

  1. ACM北大暑期课培训第一天

    今天是ACM北大暑期课开课的第一天,很幸运能参加这次暑期课,接下来的几天我将会每天写博客来总结我每天所学的内容.好吧下面开始进入正题: 今天第一节课,郭炜老师给我们讲了二分分治贪心和动态规划. 1.二 ...

  2. ACM北大暑期课培训第七天

    昨天没时间写,今天补下. 昨天学的强连通分支,桥和割点,基本的网络流算法以及Dinic算法: 强连通分支 定义:在有向图G中,如果任意两个不同的顶点 相互可达,则称该有向图是强连通的. 有向图G的极大 ...

  3. ACM北大暑期课培训第六天

    今天讲了DFA,最小生成树以及最短路 DFA(接着昨天讲) 如何高效的构造前缀指针: 步骤为:根据深度一一求出每一个节点的前缀指针.对于当前节点,设他的父节点与他的边上的字符为Ch,如果他的父节点的前 ...

  4. ACM北大暑期课培训第五天

    今天讲的扫描线,树状数组,并查集还有前缀树. 扫描线   扫描线的思路:使用一条垂直于X轴的直线,从左到右来扫描这个图形,明显,只有在碰到矩形的左边界或者右边界的时候,这个线段所扫描到的情况才会改变, ...

  5. ACM北大暑期课培训第二天

    今天继续讲的动态规划 ... 补充几个要点: 1. 善于利用滚动数组(可减少内存,用法与计算方向有关) 2.升维 3.可利用一些数据结构等方法使代码更优  (比如优先队列) 4.一般看到数值小的 (十 ...

  6. ACM北大暑期课培训第八天

    今天学了有流量下界的网络最大流,最小费用最大流,计算几何. 有流量下界的网络最大流 如果流网络中每条边e对应两个数字B(e)和C(e), 分别表示该边上的流量至少要是B(e),最多 C(e),那么,在 ...

  7. ACM北大暑期课培训第四天

    今天讲了几个高级搜索算法:A* ,迭代加深,Alpha-Beta剪枝   以及线段树 A*算法 启发式搜索算法(A算法) : 在BFS算法中,若对每个状态n都设定估价函数 f(n)=g(n)+h(n) ...

  8. 牛客网暑期ACM多校训练营(第三场)H Diff-prime Pairs (贡献)

    牛客网暑期ACM多校训练营(第三场)H Diff-prime Pairs (贡献) 链接:https://ac.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy ha ...

  9. 2019暑期北航培训—预培训作业-IDE的安装与初步使用(Visual Studio版)

    这个作业属于那个课程 2019北航软件工程暑期师资培训 这个作业要求在哪里 预培训-IDE的安装与初步使用(Visual Studio版) 我在这个课程的目标是 提高自身实际项目实践能力,掌握帮助学生 ...

随机推荐

  1. jq添加插入删除元素

    https://www.cnblogs.com/sandraryan/ append() - 在被选元素的结尾插入内容 <body> <div class="wrap&qu ...

  2. P1107 栈

    题目描述 背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即 pop(从栈顶弹出一个元素)和 push(将一个元素进栈). 栈的重要性不言 ...

  3. 解决:javac: 无效的目标发行版: 1.8

    原 解决:javac: 无效的目标发行版: 1.8 2017年06月14日 16:21:12 代码也文艺 阅读数 44795 版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...

  4. java 反射实现框架功能

    框架与框架要解决的核心问题 我做房子卖给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中.框架与工具类有区别,工具类被用户的类调用,而框架则是调用 ...

  5. printk函数 打印设备编号

    偶尔地, 当从一个驱动打印消息, 你会想打印与感兴趣的硬件相关联的设备号. 打印主次 编号不是特别难, 但是, 为一致性考虑, 内核提供了一些实用的宏定义( 在 <linux/kdev_t.h& ...

  6. linux 存取 I/O 内存

    在一些平台上, 你可能逃过作为一个指针使用 ioremap 的返回值的惩罚. 这样的使用不 是可移植的, 并且, 更加地, 内核开发者已经努力来消除任何这样的使用. 使用 I/O 内 存的正确方式是通 ...

  7. 51nod 范德蒙矩阵

    思路: 根据矩阵乘法的定义,G中的第i行第j列的元素 ai,j ,对答案的贡献为 ai,j∗ T中第j行的所有元素之和. 因此我们可以将T中根据每行的和进行排序.第i行的和可以通过公式 (ai^n−1 ...

  8. 【21.00%】【vijos P1018】智破连环阵

    描述 B国在耗资百亿元之后终于研究出了新式武器--连环阵(Zenith Protected Linked Hybrid Zone).传说中,连环阵是一种永不停滞的自发性智能武器.但经过A国间谍的侦察发 ...

  9. codeforces 1185G1 状压dp

    codeforces 1185G1. Playlist for Polycarp (easy version)(动态规划) 传送门:https://codeforces.com/contest/118 ...

  10. 查看虚拟机里的Centos7的IP(设置centos网卡)

    这里之所以是查看下IP ,是我们后面要建一个Centos远程工具Xshell 连接Centos的时候,需要IP地址,所以我们这里先 学会查看虚拟机里的Centos7的IP地址 首先我们登录操作系统 用 ...