题意:给你一个n*m的地图,现在有一束激光从左上角往右边射出,每遇到‘#’,你可以选择光线往四个方向射出,或者什么都不做,问最少需要多少个‘#’往四个方向射出才能使关系在n行往右边射出。
思路:将每一行,每一列看做二分图中的一个点,a[i,j]='#'就将第i行和第j列之间连一条边,最短路DFS即可。
1 const oo=1000000000; 2 var head,vet,next,dis,q:array[1..2100000]of longint; 3 n,m,i,j,tot,u,e,v,t,w:longint; 4 ch:ansistring; 5 6 procedure add(a,b:longint); 7 begin 8 inc(tot); 9 next[tot]:=head[a]; 10 vet[tot]:=b; 11 head[a]:=tot; 12 end; 13 14 begin 15 //assign(input,'173B.in'); reset(input); 16 //assign(output,'173B.out'); rewrite(output); 17 readln(n,m); 18 for i:=1 to n do 19 begin 20 readln(ch); 21 for j:=1 to m do 22 if ch[j]='#' then 23 begin 24 add(i,j+n); 25 add(j+n,i); 26 end; 27 end; 28 for i:=1 to n+m do dis[i]:=oo; 29 t:=0; w:=1; q[1]:=1; dis[1]:=0; 30 while t<w do 31 begin 32 inc(t); u:=q[t]; 33 e:=head[u]; 34 while e<>0 do 35 begin 36 v:=vet[e]; 37 if dis[v]=oo then 38 begin 39 dis[v]:=dis[u]+1; 40 inc(w); q[w]:=v; 41 end; 42 e:=next[e]; 43 end; 44 end; 45 if dis[n]<oo then writeln(dis[n]) 46 else writeln(-1); 47 // close(input); 48 //close(output); 49 end.