深度搜索DFS

算法思想

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。 

int check(参数)
{
    if(满足条件)
        return 1;
    return 0;
}
 
void dfs(int step)
{
        判断边界
        {
            相应操作
        }
        尝试每一种可能
        {
               满足check条件
               标记
               继续下一步dfs(step+1)
               恢复初始状态(回溯的时候要用到)
        }
}   

问题提出:

        考虑如下图所示的简单图所表示的缅因州的道路系统。在冬天里保持道路通路通畅的唯一方式就是经常扫雪。高速公路部分希望只扫尽可能少的道路上的雪,而确保总是存在连接任何两个乡镇的干净道路。如何才能做到这点呢?

   最简单的方式就是一个哈密顿图,形成一个回路,这当然可以。假设一个回路有n个点,则会有n条边;但对于树,n个点对应n-1条边,所以我可以去寻找一颗树即可。有人说那我们不形成一个圈不就是n-1了么?同学,一条线也是树的一种。将问题剥离成一个数学问题就是,如何从一个图中找到树。树有什么特征呢?这就要问什么叫做树了,树就是每对顶点之间存在唯一简单通路的无向图。所以针对这个图中的每对顶点之间也应该是有通路的,即简单连通图。这里有两种方法,即深度优先搜索和宽度优先搜索。
 此算法的思路就是先找一个主线,然后回头找到每一个点的分支。这就是回溯法,所谓回溯法,就是每一点都有相同的特征,但状态不一样。当从头遍历到尾后,要原路返回,每次返回的那个点状态不一样。仔细想想,这个递归的思想是一致的,用for i=1:N表示遍历每一种状态,用if判断每一种状态所要执行的动作,每次执行的动作模式是一样,即递归,故我们就有了如下代码:
 

//d为图的邻近矩阵,p为所生成树的邻近矩阵,
//n为图中点的个数,w为要遍历的顶点
void visit(int **d,int **p,int *T,int n,int w)
{
	cout<<w<<" ";//输出遍历的点
	T[w]=1;//已经遍历的点,要加进新增的树中
	for(int i=0;i<n;i++){//遍历每个点的所有状态,即分支
		if(d[w][i]==1&&T[i]!=1){//如果有通路,且点不在树中,则记录边,同时访问该分支
			p[w][i]=1;//记录边
			visit(d,p,T,n,i);//访问该分支
		}
	}
}
 
void DFS(int **d,int **p,int n)
{
	int *T=new int[n];//建立新建树的顶点集
	memset(T,0,sizeof(int)*n);
	visit(d,p,T,n,0);//第一个作为初始值,即从第一个点开始遍历
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值