首页 > 其他分享 >DFS基础与回溯

DFS基础与回溯

时间:2024-02-13 20:33:19浏览次数:27  
标签:dep -- 基础 DFS int B1 B2 回溯 C2

回溯法简介

回溯法一般使用DFS(深度优先搜索(递归))实现,DFS是一种遍历或搜索图,树或图像等数据结构的算法。上述数据结构不保存下来就是回溯法。
常见的是搜索树,排列型搜索树(节点数一般为n!)与子集型搜索树(节点数一般为2n)。

DFS从起始点开始,沿着一条路尽可能深入,直到无法继续回溯到上一节点为止,继续搜索,直到遍历完整个树或图。DFS使用栈与递归管理节点,一般使用递归。

排列树

graph TB A((A)) B1((B1)) C1((C1)) B2((B2)) C2((C2)) A-->B1 A-->B2 B1-->C1 B2-->C2

子集树

graph TB A((A)) B1((B1)) C1((C1)) C2((C2)) B2((B2)) D1((D1)) D2((D2)) A-->B1 A-->B2 B1-->C1 B1-->C2 B2-->D1 B2-->D2

2n(n=2)即4种方案。

回溯法模板

graph TB A((1)) B1((2)) C1((3)) B2((3)) C2((2)) A-->B1 A-->B2 B1-->C1 B2-->C2 D[图例为1~3的全排列,后略] D
//求1~n的全排列
int a[N];
bool vis[N];//表示数字i(或某个元素)是否使用过

void dfs(int dep) {

    //当dep深度等于n+1时说明n层都已经算完了,直接输出结果
    if (dep == n + 1) {
        for (int i = 1; i <= n; i++)cout << a[i] << ' ';
        cout << '\n';
        return;
    }
	//以上为递归出口

	//向下搜索,枚举范围
    for (int i = 1; i <= n; i++) {
        //排除不合法路径,如果i使用过了了就不能用了
        if (vis[i])continue;

        //修改状态,我们选上了,i现在已经被我们用了
        vis[i] = true;
        a[dep] = i;

        //向下一层递归,形成一个搜索树
        dfs(dep + 1);

        //恢复现场,只有恢复了现场我们才能不受干扰地向下一个分支进行递归
        vis[i] = false;
    }
}

例题

N皇后问题

#include <bits/stdc++.h>
using namespace std;
#define int long long

const int N = 15;
int n, ans;

int vis[N][N];//表示被多少个皇后占用了,等于0表示可以放皇后

void dfs(int dep) {
	if (dep == n + 1) {
		ans++;
		return;//递归出口
	}

	//遍历棋盘上的这一层
	for (int i = 1; i <= n; i++) {
		if (vis[dep][i])continue;//不为0,这个位置不能放,找下一个位置

		//修改状态
		for (int _i = 1; _i <= n; ++_i)vis[_i][i]++;//列加1,因为我们是一行行枚举的,所以行可以不用加1
		//四个方向的米字,_i是横轴,_j是纵轴
		for (int _i = dep, _j = i; _i >= 1 && _j >= 1; --_i, --_j)vis[_i][_j]++;
		for (int _i = dep, _j = i; _i <= n && _j >= 1; ++_i, --_j)vis[_i][_j]++;
		for (int _i = dep, _j = i; _i >= 1 && _j <= n; --_i, ++_j)vis[_i][_j]++;
		for (int _i = dep, _j = i; _i <= n && _j <= n; ++_i, ++_j)vis[_i][_j]++;

		dfs(dep + 1);//向下一层递归,一直递归到递归出口,答案加一,退出递归,准备恢复现场(会形成一个树形结构)

		//恢复现场,准备下一次搜索
		for (int _i = 1; _i <= n; ++_i)vis[_i][i]--;
		for (int _i = dep, _j = i; _i >= 1 && _j >= 1; --_i, --_j)vis[_i][_j]--;
		for (int _i = dep, _j = i; _i <= n && _j >= 1; ++_i, --_j)vis[_i][_j]--;
		for (int _i = dep, _j = i; _i >= 1 && _j <= n; --_i, ++_j)vis[_i][_j]--;
		for (int _i = dep, _j = i; _i <= n && _j <= n; ++_i, ++_j)vis[_i][_j]--;
	}
}

signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	//每一层必定只有一个皇后,可通过枚举每一层皇后的位置来搜索所有可能解
	//层数到n+1时表示找到了一个可行解,不可行的解都到不了n+1层

	cin >> n;
	dfs(1);
	cout << ans << '\n';
	return 0;
}

标签:dep,--,基础,DFS,int,B1,B2,回溯,C2
From: https://www.cnblogs.com/breadcheese/p/18014803

相关文章

  • 基础数据结构笔记
    链表与邻接表:树与图的存储 单链表  画个图就很好理解了   例题826.单链表acwing——826.单链表_awcing826-CSDN博客实现一个单链表,链表初始为空,支持三种操作:(1)向链表头插入一个数;(2)删除第k个插入的数后面的数;(3)在第k个插入的数后插入一个数现在要......
  • 第二章 语法基础
       目  录1.第一个Python程序 2.数据与数据类型 3.数据类型转换 4.标识符 5.变量 6.常量 7.Python运算符 8.表达式 9.语句 10.实例: 语法基础    任何一段计算机程序都是由一组计算机能够理解的指令构成,其中每条指令都表现为遵循......
  • 2024牛客寒假算法基础集训营3
    M题智乃的36倍数(normalversion)错解幂运算写成了乘~#include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'#defineintlonglong#definedebug(x)cout<<x<<""<<endl;#define_debug(a,n)for(inti=0;i<n;i++)......
  • 网络通信基础知识学习笔记
    一.图解网络为什么需要TCP/IP网络模型:为了适应互联网环境下多种多样的设备,设计的一套通用的网络协议对于同一台设备进程间的通信方式:管道,消息队列,共享内存,信号量TCP/IP网络模型的分层:应用层:用户能够直接接触到的层次,互联网软件都是在应用层进行实现.......
  • python基础学习5-面向对象
    类创建class类名():#类名首字母大写,()可写可不写pass对象对象名=类名()类的组成classStudent:school='北京xx学校'#类属性,定义在类中方法外的变量#初始方法def__init_......
  • 2024牛客寒假算法基础集训营1
    2024牛客寒假算法基础集训营1A解题思路:按照\(dfs\)出现顺序暴力判断即可。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusingi128=__int128_t;usingpiii=pair<ll,pai......
  • 苦瓜:瑞安基础调教课
    第01课声乐歌声基本概念谐波和噪波谐波:基频决定声音的音高噪波:没有特定音高的部分泛音频率是基频的整数倍基频只有音高,泛音决定音色共振峰歌手声音从伴奏中透出来,男低女高共鸣胸腔共鸣:最低位,决定基频能量,浑厚稳重;不能太强口腔共鸣:中频泛音,决定咬字、口型......
  • Codeforces Round 303 (Div. 2)C. Kefa and Park(DFS、实现)
    @目录题面链接题意题解代码总结题面链接C.KefaandPark题意求叶节点数量,叶节点满足,从根节点到叶节点的路径上最长连续1的长度小于m题解这道题目主要是实现,当不满足条件时直接返回。到达叶节点后统计答案,用vector存图的话,无向图时,叶节点的边只有一条,也就是\(g[i].size()......
  • Poj 2531 Network Saboteur(DFS+剪枝)
    2531--NetworkSaboteur(poj.org)#include<iostream>#include<cstring>usingnamespacestd;constintN=30;intC[N][N],n,ans;boolgroup[N];voidDFS(intnum,intsum){group[num]=true;inttmp=sum;for(inti=1;i<=n;i++){......
  • 补基础题(BFS)
    P1135奇怪的电梯-洛谷|计算机科学教育新生态(luogu.com.cn)#include<iostream>#include<queue>#include<cstring>usingnamespacestd;constintN=210;intK[N],n,A,B,vis[N];structnode{intnow,step;};#definecheck(a)(a>=1&&a<=n......