双向bfs和双向dfs

双向bfs和双向dfs

1. 算法分析

当进行的变换是可逆的时候,且规定步数的上限时,可以使用双向dfs或双向bfs从源点和终点一起搜索。这样可以把时间从O(n)->O(n/2)
如果dfs调栈超过1e5时,那么考虑双向bfs

写法技巧

  1. 双向dfs
    第一个dfs先搜索前一半的空间,打表存储所有可达的值
    第二个dfs搜索后一半的空间,然后查询是否在前一半空间中出现过

  2. 双向bfs
    维护两个队列,当两个队列均非空时才能继续进行循环。循环内不断对元素较少的那个队列进行bfs操作

2. 例题

2.1 双向dfs

acwing171 送礼物
题意:
达达帮翰翰给女生送礼物,翰翰一共准备了N个礼物,其中第i个礼物的重量是G[i]。
达达的力气很大,他一次可以搬动重量之和不超过W的任意多个物品。
达达希望一次搬掉尽量重的一些物品,请你告诉达达在他的力气范围内一次性能搬动的最大重量是多少。N~46, W,G[i]~int
题意: 第一个dfs打表记录前n/2的所有可能和。第二个dfs找到小于等于w-sum的最大的那个
代码:

#include <bits/stdc++.h>

using namespace std;

int const N = 47;
int a[N], cnt = 1, weight[1 << 25], w, n, k, ans;

void dfs1(int u, int sum) {
   
    if (u == k) {
   
        weight[cnt++] = sum;
        return;
    }
    
    dfs1(u + 1, sum);  // 不选第u个
    if (sum + 0ll + a[u] <= w) dfs1(u + 1, sum + a[u]);  // 选第u个
}

void dfs2(int u, int sum) {
   
    
    // 当找完后n/2个后,二分查找小于等于w-s的最大值
    if (u >= n) {
   
        int l = 0, r = cnt - 1;
        while (l < r
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值