BFS 广度优先遍历详见搜索与图论-BFS
void bfs()
{int hh = 0,tt = 0;q[0] = 1;//队列数组while(hh <= tt){int t = q[hh++];for(int i = h[t];i != -1;i = ne[i]){int j = e[i];if(判断)q[++tt] = j;}}
}
题目描述
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。
所有边的长度都是 1,点的编号为 1∼n。
请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 −1。
输入格式
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 a 和 b,表示存在一条从 a 走到 b 的长度为 1 的边。
输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。
数据范围
1 ≤ n,m ≤ 1e5
输入样例
4 5
1 2
2 3
3 4
1 3
1 4
输出样例
1


#include
using namespace std;const int N = 100010;int h[N],ne[N], e[N], idx;
int dist[N];
int st[N];
int n, m;void add(int a, int b)//邻接表存储图
{e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}void bfs()
{memset(dist, 0x3f, sizeof(dist));dist[1] = 0;//从1号节点开始,距离为0queue q;//队列q.push(1);//1号节点入队列st[1] = 1;//1到1的距离为0,已经求出while(q.size())//对列非空,就一直往后搜索{int t = q.front();//队头出队,找该点能到的点q.pop();for(int i = h[t]; i != -1; i = ne[i])//遍历所有t节点能到的点,i为节点索引{int j = e[i];//通过索引i得到t能到的节点编号if(!st[j])//如果没有遍历过{dist[j] = dist[t] + 1;//距离为t号节点的距离+1q.push(j);//节点入队st[j] = 1;//入队后标记,已经遍历过了}}}
}int main()
{cin >> n >>m;memset(h, -1, sizeof h);//初始化,所有节点没有后继,后继都是-1for(int i = 0; i < m; i++)//读入所有边{int a, b;cin >> a >> b;add(a, b);//加入邻接表}bfs();//广度优先遍历cout << (dist[n] == 0x3f3f3f3f ? -1 : dist[n]);system("pause");return 0;
}
#include
using namespace std;const int N = 100010;int n, m;
int h[N], e[N], ne[N], idx;
int d[N], q[N];void add(int a, int b)
{e[idx] = b;ne[idx] = h[a];h[a] = idx;idx ++ ;
}int bfs()
{int hh = 0;int tt = 0;q[0] = 1;memset(d, -1, sizeof d);d[1] = 0;while (hh <= tt){int t = q[hh ++];for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (d[j] == -1){d[j] = d[t] + 1;tt ++;q[tt] = j;}}}return d[n];
}int main()
{cin >> n >> m;memset(h, -1, sizeof h);for (int i = 0; i < m; i ++ ){int a, b;cin >> a >> b;add(a, b);}cout << bfs() << endl;return 0;
}