您的位置:首页 > 其它

周报1——浅谈DFS算法及其应用

2019-01-24 15:56 99 查看
版权声明:这是ZYF老师的劳动成果,希望能得到你们的支持,转载请链接,谢谢配合! https://blog.csdn.net/qq_41332995/article/details/86627448

        首先自我介绍,我叫ZYF,来自广东中山(因孙中山而得名),是一个七年级的学生,目前在中山纪念中学学习信息学,主修Pascal,也会C++。

        这是周报的新起点,我将会在每周定期更新,如有时间冲突也会补上,谢谢大家的支持。

        这周我们来谈一谈最基础的入门算法——DFS。

        想必DFS大家并非陌生,不管是背过模板还是做过题,都会或多或少了解DFS。但是我却对DFS有自己的看法与了解。

        DFS,全名是深度优先搜索。顾名思义,它使用的是深度优先遍历。 深度优先搜索的过程是:

        (1)访问顶点V

        (2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;

        (3)如果有顶点尚未访问,会从当点重新进行深度优先遍历,直到所有点被遍历。

        说了这么多干货,我们看几张图来了解过程:

 

        这时上面的粉色部分,便是DFS极其重要的一步:回溯

        回溯需要注意什么:

        1.改变状态(否则会有答案错误),回到搜索前的状态。

        2.改变参数,使DFS能正常结束。

        听了这么多,是否了解DFS呢?

        再来一点注意事项:一定要有结束条件!一定要有结束条件!一定要有结束条件!(重要的事情说三遍)

        假如你没有结束条件,程序只会无休止的运行下去。

        这是许多人会问:

      DFS这么慢,为什么要用呢?

        1.DFS是某些正解算法的基础(比如DP),甚至能A掉某些题(但是数据会非常水)。

        2.DFS可以拿到部分分(尤其是DP),假如没有想出正解或者不确定正解,可以用DFS拿到能拿的分。

        3.许多题目加了剪枝就可以过(大多数是水过的),成为正解。

        4.提高组常用的对拍,用来检测程序正确性。

        一个简单的模板:

[code]procedure search(参数表);
begin
if 到达目标
begin
更新答案;
退出;
end
else
begin
search(改变参数);
回溯;
end;
end;

        当然,你也可以用数据结构存储参数,实现改变参数的目的。

        例题:迷宫问题

        题目大意:给你一个N*N的地图,某些点有障碍物,每次可沿点上下左右移动一格,求起点到终点的路径总数。

        分析:一道经典的DFS题,深度优先遍历找到所有的路径,并统计答案。

        参考程序:(抱歉我是P党)

[code]const
ff:array[1..4,1..2]of longint=((1,0),(-1,0),(0,1),(0,-1));
var
x,y,ans,sx,sy,fx,fy,n,m,t,i:longint;
bz:array[-1..1000,-1..1000] of boolean;
function check(shu1,shu2:longint):boolean;
begin
if(shu1 in[1..n]) and(shu2 in[1..m]) then exit(true);
exit(false);
end;
procedure search(x,y:longint);
var
ii,xx,yy:longint;
begin
xx:=0;
yy:=0;
if (x=fx) and (y=fy) then
begin
ans:=ans+1;
exit;
end
else
begin
for ii:=1 to 4 do
begin
xx:=x+ff[ii,1];
yy:=y+ff[ii,2];
if check(xx,yy)=true then
begin
if bz[xx,yy]=false then
begin
bz[xx,yy]:=true;
search(xx,yy);
bz[xx,yy]:=false;
end;
end;
end;
end;
end;
begin

readln(n,m,t);
readln(sx,sy,fx,fy);
bz[sx,sy]:=true;
for i:=1 to t do
begin
readln(x,y);
bz[x,y]:=true;
end;
search(sx,sy);
writeln(ans);

end.

        推荐例题:LG P1219 P1101 P1019 P1605 P1040 P1092 (试炼场链接:洛古试炼场)(题目在普及练习场2.7)

        好了,本周周报就到此为止,下周的主题是:浅谈DFS剪枝技巧及其应用

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: