树和图的宽度优先遍历与深度优先遍历
树和图的两种遍历方式即为特殊的DFS和BFS
用单链表储存树和图时,从每一个节点的头指针只能储存当前节点能到达的下一层的节点
宽度优先遍历没有进行递归所以每一次搜索都是以头结点指向的位置
例如 1->2 1->3 1->5 2->8 3->6 3->7
即h[1]->5->3->2->-1;
h[2]->8->-1;
h[3]->7->6->-1;
宽度遍历和深度遍历的区别就是
深度优先遍历每搜一次就进入递归调用自身,使得搜索的节点的头指针发生变化即变成了指向当前节点的头指针
然后就变成了搜索此节点能到达的下一层
宽度优先遍历没有进行递归也就是一直搜索当前节点能到达的下一层节点直到节点搜索完时再搜索下一节点
宽度优先遍历题目:
给定一个n个点m条边的有向图,图中可能存在重边和自环。
所有边的长度都是1,点的编号为1~n。
请你求出1号点到n号点的最短距离,如果从1号点无法走到n号点,输出-1。
输入格式
第一行包含两个整数n和m。
接下来m行,每行包含两个整数a和b,表示存在一条从a走到b的长度为1的边。
输出格式
输出一个整数,表示1号点到n号点的最短距离。
数据范围
1≤n,m≤1e5
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int N=100010; 6 int n,tt=0,hh=0,m,idx=0; 7 int e[N],ne[N],q[N]; 8 int d[N],h[N]; 9 void add(int a,int b) 10 { 11 e[idx]=b,ne[idx]=h[a],h[a]=idx++; 12 } 13 void bfs() 14 { 15 q[0]=1; 16 memset(d,-1,sizeof(d)); 17 d[1]=0; 18 while(hh<=tt) 19 { 20 int t=q[hh++]; 21 for(int i=h[t];i!=-1;i=ne[i]) 22 { 23 int j=e[i]; 24 if(d[j]==-1) 25 { 26 d[j]=d[t]+1; 27 q[++tt]=j; 28 } 29 } 30 } 31 cout<<d[n]<<endl; 32 } 33 int main() 34 { 35 memset(h,-1,sizeof h); 36 cin>>n>>m; 37 for(int i=1;i<=m;i++) 38 { 39 int a,b; 40 cin>>a>>b; 41 add(a,b); 42 } 43 bfs(); 44 return 0; 45 }