Dfs学习笔记

DFS基于递归思想,有两个重要的标志,也就是两个数组,一个用来标记该点是否被访问过,一个用来把该点放入数组---即存答案.

//注意bool数组初始化默认为false

模板

void dfs()//参数用来表示状态,一般什么在变化什么作参数.
 {
     if(到达终点状态)
     {
         ...
         return;
     }
     if(越界或者是不符合法状态)//剪枝
         return;
     for(扩展方式)
     {
         if(扩展方式所达到状态合法)
         {
             ....//根据题意来添加
             标记;
             dfs();
             修改(剪枝);
             (还原标记);//此处直接按正常思维,这一位存完了,恢复
             //是否还原标记根据题意,如果加上(还原标记)就是 回溯法
         }
     }
 }

几个注意点

1.不要把递归想得太复杂,即有时候不用一定要把递归想到底,就按正常思维,处理掉当前的工作,下一步交给下一步递归去完成,每一步递归都完成自己工作就皆大欢喜.

2.扣几个细节

        2.1.以三的全排列为例,完成第一次123排列,回到2的位置时,存放数字2的赋值步骤已经结束,下一步执行的是恢复现场即把2恢复,然后for循环就会跳到存放数字3的步骤,把3存入第二个位置,dfs靠的就是这样不会重复把2再存放进去(其实和第一点说的一样,不用扣的太深,自己会解决问题).

        2.2.for循环只是遍历数字,实际上如果不进入if的话,一直是在当前位置--要存放的第几个位置,只有进入之后才会进入下一个位置,注意不能搞混位置和数字

3.要注意下标,留意数组思维惯性,应该从1开始,从0会错位

4.自己可以调试一步一步走一遍,印象会深很多.

acwing样例

int dfs(int u)
{
    st[u] = true; // st[u] 表示点u已经被遍历过

    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j]) dfs(j);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值