宽度优先搜索
2010-10-11 21:18
225 查看
4.3 宽度优先搜索
宽度优先搜索(又称广度优先搜索)与深度优先搜索同为搜索,但策略完全不同。
深度优先问题就是一般所说的递归、回溯问题,每次沿一个节点展开其下层一个节,然后再下层一个节点,直到找到一个结果为止再返回上层。
宽度优先搜索是每次把当前层每个节点对应的下一层所有节点全部展开,再判断是否有目标状态出现,如果有则这就是最少步数的答案;否则再把展开的新一层的下一层全部展开,直到展开的节点中出现目标状态为止。
宽度优先搜索问题中的每个节点要存放哪些数据是很重要的,一般用record型自定义型数据类型存放。一般至少要存放的数据有:父节点、当前状态数据。父节点是用来存放其父节点,以便在找到结果时打印答案。另外,宽度搜索中要判重(一般通过一个逻辑数组)。
广度优先搜索基本框架:
Procedure Bfs;
Begin
把所有结点标为“未访问”
将起点入队,并标记为“已访问”
repeat
for 检查所有与队首结点相连的结点 do
begin
if 新结点合法 且 新结点没有被访问过 then
begin
将新结点放入队列
计算新结点的最短路径值(=到达它的结点的路径值+1)
如果该新结点就是目标点,则输出最短路径值并退出
end;
end;
队首出队 (inc(head))
until 队列为空 (head>tail)
输出无解信息。(有解的已经在上面直接退出了)
End;
另外,如果题目没有保证初始状态一定不等于目标状态,需要在运行BFS之前特判一下是否发生初始状态直接和目标状态相等的情况。
深搜和广搜的区别:
深搜并不能保证第一次遇到目标点就是最短路径,因此要搜索所有可能的路径,因此要回溯,标记做了之后还要取消掉,因此同一个点可能被访问很多很多次。而广搜由于它的由近及远的结点扩展顺序,结点总是以最短路径被访问。一个结点如果第二次被访问,第二次的路径肯定不会比第一次的短,因此就没有必要再从这个结点向周围扩展――第一次访问这个结点的时候已经扩展过了,第二次再扩展只会得到更差的解。因此做过的标记不必去掉。因此同一个点至多只可能被访问一次。每访问一个结点,与它相连的边就被检查一次。因此最坏情况下,所有边都被检查一次,因此时间复杂度为O(E)。
例9:有两个无刻度标志的水壶,分别可装x升和y升(x,y为整数,x、y<=100)的水。设另有一水缸,可用来向水壶灌水或倒出水,两水壶间,水也可以相互倾灌。已知x升为满壶,y升为空壶。问如何通过倒水或灌水操作用最少步数能在y升壶中量出z(z<=100)升的水来。
输入样例1:
8 5 3
输出样例1:
step 0:8 0
step 1:3 5
step 2:3 0
step 3:0 3
type
atype=record
father,a,b:integer;
end;
btype=array [0..100,0..100] of boolean;
var x,y,z:integer;
data:array [1..10000] of atype;
bool:^btype;
procedure bfs;
var i,j,k,L:integer; open,closed:integer;
function min(a,b:integer):integer;
begin
if a<b then min:=a else min:=b;
end;
procedure out;
var i,j:integer; d:array [1..10000] of integer;
begin
j:=0; i:=closed;
repeat
inc(j); d[j]:=i; i:=data[i].father;
until i=0;
for i:=j downto 1 do
writeln('step ',j-i,':',data[d[i]].a,' ',data[d[i]].b);
close(input);close(output);
halt;
end;
procedure evaluate(i,j:integer);
begin
bool^[i,j]:=false; inc(closed);
data[closed].a:=i; data[closed].b:=j;
data[closed].father:=open;
if j=z then out;
end;
begin
new(bool);
fillchar(bool^,sizeof(bool^),true);
open:=0; closed:=1; bool^[x,0]:=false;
data[1].a:=x; data[1].b:=0; data[1].father:=0;
if (z=x) or (z=0) then out;
repeat
inc(open); i:=data[open].a; j:=data[open].b;
k:=min(i,y-j);
L:=min(j,x-i);
if (i>0) and (j<y) and (bool^[i-k,j+k]) then evaluate(i-k,j+k);
if (j>0) and (i<x) and (bool^[i+L,j-L]) then evaluate(i+L,j-L);
if (i>0) and (bool^[0,j]) then evaluate(0,j);
if (j>0) and (bool^[i,0]) then evaluate(i,0);
if (i<x) and (bool^[x,j]) then evaluate(x,j);
if (j<y) and (bool^[i,y]) then evaluate(i,y);
until open>=closed;
writeln('No answer!');
close(input); close(output);
end;
Begin
assign(input,'input.txt'); reset(input);
assign(output,'output.txt'); rewrite(output);
readln(x,y,z); bfs;
end.
修改后程序:
program aa;
type atype=record
father,a,b:integer;
end;
var x,y,z,q:integer;
data:array[-2..10000] of atype;
bool:array[-2..100,0..100] of boolean;
procedure bfs;
var i,j,k,l:integer;
f,r:integer;
function min(a,b:integer):integer;
begin
if a<b then min:=a
else min:=b;
end;
procedure out;
var i,j:integer;
d:array[1..10000] of integer;
begin
j:=0; i:=r;
repeat
j:=j+1;
d[j]:=i;
i:=data[i].father;
until i=0;
for i:=j downto 1 do
writeln('step',j-i:3,':',data[d[i]].a:5,data[d[i]].b:5);
// 编号
halt;
end;
procedure fuzhi(i,j:integer);
begin
bool[i,j]:=true; inc(r);
data[r].a:=i; data[r].b:=j;
data[r].father:=f;
if j=z then out;
end;
begin
if z>y then exit;
fillchar(bool,sizeof(bool),false);
f:=0; r:=1; bool[x,0]:=true;
data[1].a:=x; data[1].b:=0; data[1].father:=0;
if (z=x)or(z=0) then out;
repeat
inc(f); i:=data[f].a; j:=data[f].b;
k:=min(i,y-j); l:=min(j,x-i);
if (i>0)and(j<y)and not(bool[i-k,j+k]) then fuzhi(i-k,j+k);
if (j>0)and(i<x)and not(bool[i+l,j-l]) then fuzhi(i+l,j-l);
if (j<y)and not(bool[i,y]) then fuzhi(i,y);
if (i<x)and not(bool[x,j]) then fuzhi(x,j);
if (i>0)and not(bool[0,j]) then fuzhi(0,j);
if (j>0)and not(bool[i,0]) then fuzhi(i,0);
until f>=r;
end;
begin
readln(x,y,z);
bfs;
writeln('NO');
end.
例10:砝码称重。给定n种砝码(每种个数不限)和一个整数M,求至少需要几个砝码才可以称出刚好M克。(n<=100, M<=1000)
输入:n, m,n个整数Wi表示砝码的质量。
输出:最少需要的砝码数或Impossible表示无法满足。
const maxn=100; maxm=1000;
var n,m:integer; w:array [1..maxn] of integer;
dist:array [0..maxm] of integer;
queue:array [1..maxm+1] of integer;
procedure init;
var i:integer;
begin
read(n,m);
for i:=1 to n do read(w[i]);
end;
procedure solve;
var cl,op,k,i:integer;
begin
cl:=0; op:=1;
fillchar(dist,sizeof(dist),255); -1
dist[0]:=0;
queue[1]:=0;
while cl<op do
begin
inc(cl); k:=queue[cl];
for i:=1 to n do
if (k+w[i]<=m) and (dist[k+w[i]]= -1) then
begin
dist[k+w[i]]:=dist[k]+1;
inc(op);
queue[op]:=k+w[i];
end;
end;
if dist[m]= -1 then writeln('Impossible') else writeln(dist[m]);
end;
Begin
init;
solve;
End.
修改后程序:
program aa;
var w:array[1..100] of integer;
q,dis:array[0..1000] of integer;
n,m:integer;
procedure init;
var i:integer;
begin
readln(n,m);
for i:=1 to n do read(w[i]);
end;
procedure guang;
var f,r,k,i:integer;
begin
fillchar(dis,sizeof(dis),0);
f:=0; r:=1;
q[1]:=0;
while f<r do
begin
inc(f); k:=q[f];
for i:=1 to n do
if (k+w[i]<=m)and(dis[k+w[i]]=0) then //注意条件:能加入k, 且未加入过
begin
dis[k+w[i]]:=dis[k]+1; //当前所需个数为 上一个的 加一
inc(r); q[r]:=k+w[i];
end;
end;
if dis[m]=0 then writeln('Impossible') //未加入
else writeln(dis[m]);
end;
begin
init;
guang;
end.
例11:翻币问题。有N个硬币(6≤N≤8000)正面朝上排成一排,每次将5个硬币翻过来放在原来位置,直到最后全部翻成反面朝上为止。编写程序让计算机找出步数最少的翻法,并把翻币过程及次数打印出来(用O表示正面,*表示反面)。
输入样例:
6
输出样例:
setp0:oooooo
step1:*****o
step2:oooo**
step3:***ooo
step4:oo****
step5:*ooooo
step6:******
var n:integer;
a:array [1..8000,1..3] of integer;
b:array [0..800] of boolean;
procedure calc;
var r,m:integer; open,closed:integer;
procedure out;
var i,j,k,L,h:integer;
d:array [1..5000] of integer;
st:array [1..5000] of char;
begin
write('step 0:');
for i:=1 to n do write('o');
writeln;
for i:=1 to n do st[i]:='o';
j:=0; i:=closed;
repeat
j:=j+1; d[j]:=i; i:=a[i,1];
until i=0;
for i:=j-1 downto 1 do
begin
k:=a[d[i],3]; L:=5-k;
for h:=1 to n do
if st[h]='o' then
begin
if k>0 then begin dec(k); st[h]:='*'; end;
end else
begin
if L>0 then begin dec(L); st[h]:='o'; end;
end;
write('step ',j-i,':');
for h:=1 to n do write(st[h]);
writeln;
end;
close(input); close(output);
halt;
end;
begin
fillchar(b,sizeof(b),true);
b
:=false; open:=0; closed:=1;
a[1,1]:=0; a[1,2]:=n; a[1,3]:=0;
repeat
inc(open);
m:=a[open,2];
for r:=0 to 5 do
if (m>=r) and (n-m>=5-r) and (b[m-r+5-r]) then
begin
inc(closed);
b[m-r+5-r]:=false;
a[closed,1]:=open;
a[closed,2]:=m-r+5-r;
a[closed,3]:=r;
if a[closed,2]=0 then out;
end;
until open>=closed;
writeln('No answer!');
close(input);close(output);
end;
Begin
assign(input,'input.txt'); reset(input);
assign(output,'output.txt'); rewrite(output);
read(n);
calc;
end.
修改后程序:
program aa;
var n:integer;
a:array[1..8000,1..3] of integer; //a[i,1]为前驱, a[i,2]为正面朝上的个数,a[i,3]为反面朝上的个数
b:array[0..800] of boolean; //b[i]为 正面的个数为 i 的
procedure calc;
var k,m:integer;
f,r:integer;
procedure out;
var i,j,k,l,h:integer;
d:array[1..5000] of integer;
st:array[1..5000] of char;
begin
for i:=1 to n do st[i]:='o';
j:=0; i:=r;
repeat //此循环将 结点 逆序存入 d数组
inc(j);
d[j]:=i; i:=a[i,1];
until i=0;
for i:=j downto 1 do //逆序处理
begin
k:=a[d[i],3]; l:=5-k;
for h:=1 to n do
if st[h]='o' then //当前为 正面的,取反
begin
if k>0 then
begin
dec(k); st[h]:='*';
end;
end
else begin //当前为 反面的,取反
if l>0 then
begin
dec(l);st[h]:='o';
end;
end;
write('step',j-i:2,':');
for h:=1 to n do write(st[h]);
writeln;
end;
halt;
end;
begin
fillchar(b,sizeof(b),false);
b
:=true;
f:=0; r:=1;
a[1,1]:=0; a[1,2]:=n; a[1,3]:=0;
repeat
inc(f);
m:=a[f,2]; //取正面朝上的
for k:=1 to 5 do //能翻的次数(即反面的个数)
if (m>=k)and(n-m>=5-k)and not (b[m-k+5-k]) then
begin
inc(r); b[m-k+5-k]:=true;
a[r,1]:=f;
a[r,2]:=m-k+5-k; //正面的个数:原来正-该次反+(该次正)
a[r,3]:=k;
if a[r,2]=0 then out;
end;
until f>=r;
writeln('NO');
end;
begin
readln(n);
calc;
end.
宽度优先搜索(又称广度优先搜索)与深度优先搜索同为搜索,但策略完全不同。
深度优先问题就是一般所说的递归、回溯问题,每次沿一个节点展开其下层一个节,然后再下层一个节点,直到找到一个结果为止再返回上层。
宽度优先搜索是每次把当前层每个节点对应的下一层所有节点全部展开,再判断是否有目标状态出现,如果有则这就是最少步数的答案;否则再把展开的新一层的下一层全部展开,直到展开的节点中出现目标状态为止。
宽度优先搜索问题中的每个节点要存放哪些数据是很重要的,一般用record型自定义型数据类型存放。一般至少要存放的数据有:父节点、当前状态数据。父节点是用来存放其父节点,以便在找到结果时打印答案。另外,宽度搜索中要判重(一般通过一个逻辑数组)。
广度优先搜索基本框架:
Procedure Bfs;
Begin
把所有结点标为“未访问”
将起点入队,并标记为“已访问”
repeat
for 检查所有与队首结点相连的结点 do
begin
if 新结点合法 且 新结点没有被访问过 then
begin
将新结点放入队列
计算新结点的最短路径值(=到达它的结点的路径值+1)
如果该新结点就是目标点,则输出最短路径值并退出
end;
end;
队首出队 (inc(head))
until 队列为空 (head>tail)
输出无解信息。(有解的已经在上面直接退出了)
End;
另外,如果题目没有保证初始状态一定不等于目标状态,需要在运行BFS之前特判一下是否发生初始状态直接和目标状态相等的情况。
深搜和广搜的区别:
深搜并不能保证第一次遇到目标点就是最短路径,因此要搜索所有可能的路径,因此要回溯,标记做了之后还要取消掉,因此同一个点可能被访问很多很多次。而广搜由于它的由近及远的结点扩展顺序,结点总是以最短路径被访问。一个结点如果第二次被访问,第二次的路径肯定不会比第一次的短,因此就没有必要再从这个结点向周围扩展――第一次访问这个结点的时候已经扩展过了,第二次再扩展只会得到更差的解。因此做过的标记不必去掉。因此同一个点至多只可能被访问一次。每访问一个结点,与它相连的边就被检查一次。因此最坏情况下,所有边都被检查一次,因此时间复杂度为O(E)。
例9:有两个无刻度标志的水壶,分别可装x升和y升(x,y为整数,x、y<=100)的水。设另有一水缸,可用来向水壶灌水或倒出水,两水壶间,水也可以相互倾灌。已知x升为满壶,y升为空壶。问如何通过倒水或灌水操作用最少步数能在y升壶中量出z(z<=100)升的水来。
输入样例1:
8 5 3
输出样例1:
step 0:8 0
step 1:3 5
step 2:3 0
step 3:0 3
type
atype=record
father,a,b:integer;
end;
btype=array [0..100,0..100] of boolean;
var x,y,z:integer;
data:array [1..10000] of atype;
bool:^btype;
procedure bfs;
var i,j,k,L:integer; open,closed:integer;
function min(a,b:integer):integer;
begin
if a<b then min:=a else min:=b;
end;
procedure out;
var i,j:integer; d:array [1..10000] of integer;
begin
j:=0; i:=closed;
repeat
inc(j); d[j]:=i; i:=data[i].father;
until i=0;
for i:=j downto 1 do
writeln('step ',j-i,':',data[d[i]].a,' ',data[d[i]].b);
close(input);close(output);
halt;
end;
procedure evaluate(i,j:integer);
begin
bool^[i,j]:=false; inc(closed);
data[closed].a:=i; data[closed].b:=j;
data[closed].father:=open;
if j=z then out;
end;
begin
new(bool);
fillchar(bool^,sizeof(bool^),true);
open:=0; closed:=1; bool^[x,0]:=false;
data[1].a:=x; data[1].b:=0; data[1].father:=0;
if (z=x) or (z=0) then out;
repeat
inc(open); i:=data[open].a; j:=data[open].b;
k:=min(i,y-j);
L:=min(j,x-i);
if (i>0) and (j<y) and (bool^[i-k,j+k]) then evaluate(i-k,j+k);
if (j>0) and (i<x) and (bool^[i+L,j-L]) then evaluate(i+L,j-L);
if (i>0) and (bool^[0,j]) then evaluate(0,j);
if (j>0) and (bool^[i,0]) then evaluate(i,0);
if (i<x) and (bool^[x,j]) then evaluate(x,j);
if (j<y) and (bool^[i,y]) then evaluate(i,y);
until open>=closed;
writeln('No answer!');
close(input); close(output);
end;
Begin
assign(input,'input.txt'); reset(input);
assign(output,'output.txt'); rewrite(output);
readln(x,y,z); bfs;
end.
修改后程序:
program aa;
type atype=record
father,a,b:integer;
end;
var x,y,z,q:integer;
data:array[-2..10000] of atype;
bool:array[-2..100,0..100] of boolean;
procedure bfs;
var i,j,k,l:integer;
f,r:integer;
function min(a,b:integer):integer;
begin
if a<b then min:=a
else min:=b;
end;
procedure out;
var i,j:integer;
d:array[1..10000] of integer;
begin
j:=0; i:=r;
repeat
j:=j+1;
d[j]:=i;
i:=data[i].father;
until i=0;
for i:=j downto 1 do
writeln('step',j-i:3,':',data[d[i]].a:5,data[d[i]].b:5);
// 编号
halt;
end;
procedure fuzhi(i,j:integer);
begin
bool[i,j]:=true; inc(r);
data[r].a:=i; data[r].b:=j;
data[r].father:=f;
if j=z then out;
end;
begin
if z>y then exit;
fillchar(bool,sizeof(bool),false);
f:=0; r:=1; bool[x,0]:=true;
data[1].a:=x; data[1].b:=0; data[1].father:=0;
if (z=x)or(z=0) then out;
repeat
inc(f); i:=data[f].a; j:=data[f].b;
k:=min(i,y-j); l:=min(j,x-i);
if (i>0)and(j<y)and not(bool[i-k,j+k]) then fuzhi(i-k,j+k);
if (j>0)and(i<x)and not(bool[i+l,j-l]) then fuzhi(i+l,j-l);
if (j<y)and not(bool[i,y]) then fuzhi(i,y);
if (i<x)and not(bool[x,j]) then fuzhi(x,j);
if (i>0)and not(bool[0,j]) then fuzhi(0,j);
if (j>0)and not(bool[i,0]) then fuzhi(i,0);
until f>=r;
end;
begin
readln(x,y,z);
bfs;
writeln('NO');
end.
例10:砝码称重。给定n种砝码(每种个数不限)和一个整数M,求至少需要几个砝码才可以称出刚好M克。(n<=100, M<=1000)
输入:n, m,n个整数Wi表示砝码的质量。
输出:最少需要的砝码数或Impossible表示无法满足。
const maxn=100; maxm=1000;
var n,m:integer; w:array [1..maxn] of integer;
dist:array [0..maxm] of integer;
queue:array [1..maxm+1] of integer;
procedure init;
var i:integer;
begin
read(n,m);
for i:=1 to n do read(w[i]);
end;
procedure solve;
var cl,op,k,i:integer;
begin
cl:=0; op:=1;
fillchar(dist,sizeof(dist),255); -1
dist[0]:=0;
queue[1]:=0;
while cl<op do
begin
inc(cl); k:=queue[cl];
for i:=1 to n do
if (k+w[i]<=m) and (dist[k+w[i]]= -1) then
begin
dist[k+w[i]]:=dist[k]+1;
inc(op);
queue[op]:=k+w[i];
end;
end;
if dist[m]= -1 then writeln('Impossible') else writeln(dist[m]);
end;
Begin
init;
solve;
End.
修改后程序:
program aa;
var w:array[1..100] of integer;
q,dis:array[0..1000] of integer;
n,m:integer;
procedure init;
var i:integer;
begin
readln(n,m);
for i:=1 to n do read(w[i]);
end;
procedure guang;
var f,r,k,i:integer;
begin
fillchar(dis,sizeof(dis),0);
f:=0; r:=1;
q[1]:=0;
while f<r do
begin
inc(f); k:=q[f];
for i:=1 to n do
if (k+w[i]<=m)and(dis[k+w[i]]=0) then //注意条件:能加入k, 且未加入过
begin
dis[k+w[i]]:=dis[k]+1; //当前所需个数为 上一个的 加一
inc(r); q[r]:=k+w[i];
end;
end;
if dis[m]=0 then writeln('Impossible') //未加入
else writeln(dis[m]);
end;
begin
init;
guang;
end.
例11:翻币问题。有N个硬币(6≤N≤8000)正面朝上排成一排,每次将5个硬币翻过来放在原来位置,直到最后全部翻成反面朝上为止。编写程序让计算机找出步数最少的翻法,并把翻币过程及次数打印出来(用O表示正面,*表示反面)。
输入样例:
6
输出样例:
setp0:oooooo
step1:*****o
step2:oooo**
step3:***ooo
step4:oo****
step5:*ooooo
step6:******
var n:integer;
a:array [1..8000,1..3] of integer;
b:array [0..800] of boolean;
procedure calc;
var r,m:integer; open,closed:integer;
procedure out;
var i,j,k,L,h:integer;
d:array [1..5000] of integer;
st:array [1..5000] of char;
begin
write('step 0:');
for i:=1 to n do write('o');
writeln;
for i:=1 to n do st[i]:='o';
j:=0; i:=closed;
repeat
j:=j+1; d[j]:=i; i:=a[i,1];
until i=0;
for i:=j-1 downto 1 do
begin
k:=a[d[i],3]; L:=5-k;
for h:=1 to n do
if st[h]='o' then
begin
if k>0 then begin dec(k); st[h]:='*'; end;
end else
begin
if L>0 then begin dec(L); st[h]:='o'; end;
end;
write('step ',j-i,':');
for h:=1 to n do write(st[h]);
writeln;
end;
close(input); close(output);
halt;
end;
begin
fillchar(b,sizeof(b),true);
b
:=false; open:=0; closed:=1;
a[1,1]:=0; a[1,2]:=n; a[1,3]:=0;
repeat
inc(open);
m:=a[open,2];
for r:=0 to 5 do
if (m>=r) and (n-m>=5-r) and (b[m-r+5-r]) then
begin
inc(closed);
b[m-r+5-r]:=false;
a[closed,1]:=open;
a[closed,2]:=m-r+5-r;
a[closed,3]:=r;
if a[closed,2]=0 then out;
end;
until open>=closed;
writeln('No answer!');
close(input);close(output);
end;
Begin
assign(input,'input.txt'); reset(input);
assign(output,'output.txt'); rewrite(output);
read(n);
calc;
end.
修改后程序:
program aa;
var n:integer;
a:array[1..8000,1..3] of integer; //a[i,1]为前驱, a[i,2]为正面朝上的个数,a[i,3]为反面朝上的个数
b:array[0..800] of boolean; //b[i]为 正面的个数为 i 的
procedure calc;
var k,m:integer;
f,r:integer;
procedure out;
var i,j,k,l,h:integer;
d:array[1..5000] of integer;
st:array[1..5000] of char;
begin
for i:=1 to n do st[i]:='o';
j:=0; i:=r;
repeat //此循环将 结点 逆序存入 d数组
inc(j);
d[j]:=i; i:=a[i,1];
until i=0;
for i:=j downto 1 do //逆序处理
begin
k:=a[d[i],3]; l:=5-k;
for h:=1 to n do
if st[h]='o' then //当前为 正面的,取反
begin
if k>0 then
begin
dec(k); st[h]:='*';
end;
end
else begin //当前为 反面的,取反
if l>0 then
begin
dec(l);st[h]:='o';
end;
end;
write('step',j-i:2,':');
for h:=1 to n do write(st[h]);
writeln;
end;
halt;
end;
begin
fillchar(b,sizeof(b),false);
b
:=true;
f:=0; r:=1;
a[1,1]:=0; a[1,2]:=n; a[1,3]:=0;
repeat
inc(f);
m:=a[f,2]; //取正面朝上的
for k:=1 to 5 do //能翻的次数(即反面的个数)
if (m>=k)and(n-m>=5-k)and not (b[m-k+5-k]) then
begin
inc(r); b[m-k+5-k]:=true;
a[r,1]:=f;
a[r,2]:=m-k+5-k; //正面的个数:原来正-该次反+(该次正)
a[r,3]:=k;
if a[r,2]=0 then out;
end;
until f>=r;
writeln('NO');
end;
begin
readln(n);
calc;
end.
相关文章推荐
- USACO-Section2.1 Healthy Holsteins【宽度优先搜索/深度优先搜索】
- BFS-宽度优先搜索(Breadth First Search)—1
- 广度/宽度优先搜索(BFS)
- 白书2.1.5宽度优先搜索(迷宫的最短路径)
- HDU1598 并查集(有点难度哦)//感觉又有点像和宽度优先搜索有点结合
- BFS宽度优先搜索思想
- 算法7-4:宽度优先搜索
- 广度/宽度优先搜索(BFS)
- coj1224(宽度优先搜索)
- 广度/宽度优先搜索(BFS)(给了部分题目)
- USACO-Section3.2 Magic Squares【宽度优先搜索】
- 宽度优先搜索
- CodeForces 931D 宽度优先搜索
- 【算法入门】广度/宽度优先搜索(BFS)
- BFS 宽度优先搜索——初学
- BFS宽度优先搜索思想
- 图的宽度优先搜索
- 【宽度优先搜索】poj3414 Pots
- 多叉树的宽度优先搜索BFS
- 【算法入门】广度/宽度优先搜索(DFS)