目录
项目场景:
利用bfs搜索的思想+图中邻接表的存储遍历实现在权重相同的边之中求两点之间的最短路径
问题描述
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。
所有边的长度都是 1,点的编号为 1∼n。
请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 −1。
输入格式
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 a 和 b,表示存在一条从 a 走到 b 的长度为 1 的边。
输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。
数据范围
1≤n,m≤105
输入样例:
4 5
1 2
2 3
3 4
1 3
1 4
输出样例:
1
思路分析:
邻接表+bfs实现 对于bfs遍历 其核心思想是构造一个队列 从队头元素开始 取队头元素并弹出后进行相关操作 而对于图的遍历 邻接表的遍历思想在这里也会用到 详情可参照代码部分
实现代码:
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int N = 100010,M = 2*N;
int idx,h[N],e[M],ne[M];//图的存储-邻接表中所需要定义的数组
int d[N];//记录每个节点到编号为1的节点之间的距离
int n,m;
//图的存储中必有的插入操作
void add(int a,int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
//bfs在图的存储中的应用
int bfs(){
//定义队列
queue<int> q;
//初始化距离数组
memset(d,-1,sizeof(d));
//将1号编号到自己的距离设置为1
d[1] = 0;
//将1号节点入队
q.push(1);
//当队列不为空时
while(q.size()){
//获取队头元素
auto t = q.front();
//弹出队头元素
q.pop();
//遍历邻接表
for(int i=h[t];i!=-1;i=ne[i]){
//获得当前节点下一个节点的编号 作用为向后走一步
int j = e[i];
//如果j节点没有被访问过
if(d[j]==-1){
//j节点到1号编号的距离+1
d[j] = d[t]+1;
//将j节点入队 此时队不会为空
q.push(j);
}
}
}
//返回节点n到节点1的距离
return d[n];
}
int main(){
//初始化邻接表
memset(h,-1,sizeof(h));
cin>>n>>m;
//输入边
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
//有向图只需要添加一条边即可
add(a,b);
}
cout<<bfs()<<endl;
return 0;
}