C++ dfs 有关图的知识(四十五)【第六篇】

今天继续上次的写,dfs 有关图的知识。

1.关于字典序最小的dfs序

我们刚才说图的 DFS 不唯一,在方案不唯一的情况下我们经常会面临求字典序最小的方案的问题。

那先来看字典序是什么,对于字符串大家都知道字典序比较,两个字符串从头开始比,遇到第一个不同的位置,谁小谁字典序就小。特殊地,当一直都是一样,直到某个字符串后边没有字符了,那就是没有字符的小,还有字符的大。

对于方案,字典序的意思和我们谈论字符串时基本相同。把两种方案每一次的选择列出来,从第一个位置开始比,遇到某个位置两个方案选择不同,哪个方案选择的小,字典序就小。

比如

1 2 5 3 4

1 2 4 3 5

 
  

从第一个数开始比,会发现到第 3 个位置,上边的方案是 5 ,下边是 4 ,不一样了,那下边的方案这个数小,就是下边的方案字典序小。

那对于一张连通图,我们如何能够求出字典序最小的 DFS 序,首先肯定要从 1 号点开始,然后要求每一次走的都是当前能走的编号最小的点,因为字典序是一旦当前位置小了,不管后边怎么大,这个字典序都小,这就是一个贪心的思想。

实际写代码的时候我们只需要把邻接表的每一行都从小到大排序,按照这样的顺序进行图的遍历,得到的 DFS 序就是最小的了。

C++ dfs 有关图的知识(四十五)【第六篇】_第1张图片

比如这个图,字典序最小的 DFS 序是 1,2,4,5,3,6 。

那回顾之前学习的迷宫问题,如果约定往上走一步是'U',往下走一步是'D',往左走一步是'L',往右走一步是'R',一个从起点走到终点的方案就可以写成一个字符串,现在希望求解字典序最小的方案,如何去做?

其实对于当前所在的点,下一步就按照下('D'),左('L'),右('R'),上('U')的顺序依次来尝试就可以了,相当于每一步也是选了字典序尽可能小的方案。

int dir[4][2] = {
    {1, 0}, // 下('D')
    {0, -1}, // 左('L')
    {0, 1}, // 右('R')
    {-1, 0} // 上('U')
};

你可能感兴趣的:(C++,算法,深度优先)