搜索与图论———DFS

DFS(深度优先搜索)

用于遍历或搜索图或树的算法
在没有剪枝,DFS=暴力搜索
时间O(n!)以上
模板

ans//答案
void dfs(层数,其他参数){
if(出局判断){//到大最低层,或者满足条件退出
	更新答案//答案一般用全局变量表示
return//返回上一层
}
(剪枝)//再进一步dfs之前剪枝
for(枚举下一层可能出现的情况)//对每一个情况继续dfs
if(use[i]==0){//如果状态i没有使用过,就可以竟然下一层
		used[i]=1;//标记状态i,表示已经用过,在更底层不能再使用
		dfs(层数+1,其他参数);//下一层
		used[i]=0;//恢复状态,回溯时不影响上一层对这个状态的使用
	}
	return;//放回上一层
}

全排列

//全排列
//递归实现
//可以用栈维护

#include<bits/stdc++.h>
using namespace std;
int n,pd[100],used[100];//pd是判断是否用过这个数
void print()//输出函数
{
    int i;
    for(i=1;i<=n;i++)
    printf("%5d",used[i]);//保留五位常宽
    cout<<endl;
}

void dfs(int k)//深搜函数,当前是第k格
{
    int i;
    if(k==n) //填满了的时候
    {
        print();//输出当前解
        return;
    }
 
for(i=1;i<=n;i++)//1-n循环填数
    {
        if(pd[i]==0)//如果当前数没有用过
        {
            pd[i]=1;//标记一下
            used[k+1]=i;//把这个数填入数组
            dfs(k+1);//填下一个
            pd[i]=0;//回溯
        }
    }
}
int main()
{
    cin>>n;
    dfs(0);//注意,这里是从第0格开始的!
    return 0;
}

迷宫

#include<iostream>
using namespace std;
int n,m,t ,a[10][10],v[10][10],ans;
int d[][2]={{0,1},{1,0},{0,-1},{-1,0}};

struct point{
	int x,y;
};//点有x轴和y轴

point start ,fi;//创建起点和终点

void dfs (point s){//x选择在s点下步的点
	point temp;//s可移动点
	
	if(s.x==fi.x&&s.y==fi.y){//到达终点,可达路径+1
	ans++;
	return ;//返回上个点
	}
	
	for(int i=0;i<4;i++){//遍历每个点的四个方向
		temp.x=s.x+d[i][1];//四个方向的移动
		temp.y=s.y+d[i][0];
			if(temp.y>=1&&temp.y<=n&&temp.x>=1&&temp.x<=m&&a[temp.y][temp.x]==0&&v[temp.y][temp.x]==0){//若下个的点在迷宫范围且没有被访问过的非障碍点
				v[temp.y][temp.x]=1;//标记选择的点,防止重复遍历
				dfs(temp);//一选择的先进行遍历
				v[temp.y][temp.x]=0;//撤销标记
		}
	}
	return;
}
int main(){
	cin>>n>>m>>t;
	cin>>start.x>>start.y>>fi.x>>fi.y;
	
	point temp;
	
	for(int i=0;i<t;i++){
		cin>>temp.x>>temp.y;
		a[temp.y][temp.x]=1;//障碍点
	}
	
	v[start.y][start.x]=1;//起点坐标
	
	dfs(start);
	cout<<ans;
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值