一些普及组会用到的DFS模板,其他的DFS我感觉普及组不会用到所以暂且搁着,等之后有时间了再细写w
(至于我为什么最近不写TG相关只写最基础的PJ的内容,请戳这里了解)
dfs各种模板big集合
1. dfs框架
#include<bits/stdc++.h>
using namespace std;
int n, m;//n:有几个数 m:要几个
bool used[ ];//是否用过
int ans[ ];//答案
void dfs(int u){
if (出局判断){//到头就走
做要做的事
return ;//退出
}
for (int i = 开始的地方; i <= n; i++)//从上一个数开始依次增加,枚举每一种情况
if (used[i] == 0) {//判断是否用过
加入结果 设为用过
dfs(u + 1);//下一个数字
回溯:回到没用过
}
return ;//退出
}
int main(){
输入 初始化
dfs(1);//开始搜索,从1开始
return 0;
}
2. dfs全排列
#include<bits/stdc++.h>
using namespace std;
int n;//有几个数
bool used[10];//是否用过
int ans[10];//答案
void dfs(int u){//u表示上一个
if (u == n + 1){//到头就走
for (int i = 1; i <= n; i++) printf("%d ", ans[i]);//输出*1
printf("
");//输出*2
return ;//退出
}
for (int i = 1; i <= n; i++)//枚举每一种情况
if (used[i] == 0)//判断是否用过
{
ans[u] = i;//加入结果
used[i] = 1;//设为用过
dfs(u + 1);//下一个数字
used[i] = 0;//回溯:回到没用过
}
return ;//退出
}
int main(){
cin>>n;//输入
memset(used, 0, sizeof(used));//记得清零
dfs(1);//开始搜索,从1开始
return 0;
}
3. dfs组合+判断素数
#include<bits/stdc++.h>
using namespace std;
int n, m;//n:有几个数 m:要几个
int a[30];//数字
int ans = 0;//方案个数
bool prime(int d) //素数检测
{
int s = sqrt(d);
for (int i = 2; i <= s; i++)
if (d % i == 0) return 0;
return 1;
}
void dfs(int u, int opt, int sum){
if (u == m + 1)//到头就走
{
if (prime(sum))//判断是否为素数
ans++;
return ;//退出
}
for (int i = opt + 1; i <= n; i++)//从上一个下标开始依次增加,枚举每一种情况
dfs(u + 1, i, sum + a[i]);//下一个数字
return ;//退出
}
int main(){
scanf("%d %d", &n, &m);//输入
for (int i = 1; i <= n; i++) scanf("%d", &a[i]); //输入
dfs(1, 0, 0);//开始搜索,从1开始
printf("%d", ans);
return 0;
}
4.dfs排列问题
#include<bits/stdc++.h>
using namespace std;
int n, m;//n:有几个数 m:要几个
bool used[10];//是否用过
int ans[10];//答案
void dfs(int u){
if (u == m + 1)//到头就走
{
for (int i = 1; i <= m; i++) printf("%d ", ans[i]);//输出*1
printf("
");//输出*2
return ;//退出
}
for (int i = 1; i <= n; i++)//枚举每一种情况
if (used[i] == 0)//判断是否用过
{
ans[u] = i;//加入结果
used[i] = 1;//设为用过
dfs(u + 1);//下一个数字
used[i] = 0;//回溯:回到没用过
}
return ;//退出
}
int main()
{
scanf("%d %d", &n, &m);//输入
memset(used, 0, sizeof(used));//记得清零
dfs(1);//开始搜索,从1开始
return 0;
}
5.dfs组合问题
#include<bits/stdc++.h>
using namespace std;
int n, m;//n:有几个数 m:要几个
bool used[30];//是否用过
int ans[30];//答案
void dfs(int u){
if (u == m + 1)//到头就走
{
for (int i = 1; i <= m; i++) printf("%d ", ans[i]);//输出*1
printf("
");//输出*2
return ;//退出
}
for (int i = ans[u - 1] + 1; i <= n; i++)//从上一个数开始依次增加,枚举每一种情况
if (used[i] == 0)//判断是否用过
{
ans[u] = i;//加入结果
used[i] = 1;//设为用过
dfs(u + 1);//下一个数字
used[i] = 0;//回溯:回到没用过
}
return ;//退出
}
int main(){
scanf("%d %d", &n, &m);//输入
memset(used, 0, sizeof(used));//记得清零
ans[0] = 0;//重点:注意当u=1时的极限情况清零
dfs(1);//开始搜索,从1开始
return 0;
}
注:本文模板来源参考于大佬笔记
(这个大佬的BLOG里全部都是干货全部都是精品我强烈推荐!!!)