问题背景
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。
所有边的长度都是 1,点的编号为 1∼n。
请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 −1。
思路
- 用vector模拟邻接表存储图
- 宽度优先搜索比较容易解决层序遍历的问题
- 使用st数组标记点是否被遍历过,最先遍历的点一定是距离最短的,因此要加一个判断
- dist数组标记从点1到点i的距离,初始化为dist[1]=0,此后每往后遍历一个节点,它的距离都+1
代码
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int N=1e5+10;
vector<int> v[N];//邻接表储存图
queue<int> q;//bfs需要使用队列的数据结构
int n,m;
int dist[N];//距离数组,记录从点1到点i的距离
int st[N];//状态数组,标记是否被遍历过
void bfs()
{
q.push(1);
dist[1]=0;//
while(q.size())//当队列不空
{
int t=q.front();//取出队头
q.pop();
for(auto x:v[t])//x是t所连接的所有点,遍历
{
if(!st[x])//如果没有被遍历过
{
dist[x]=dist[t]+1;//x点距离为t+1
q.push(x);//已经被遍历,入队
st[x]=1;//标记为已被遍历
}
}
}
if(dist[n]==0x3f3f3f3f) puts("-1");
else cout<<dist[n];
}
int main()
{
cin>>n>>m;
memset(dist,0x3f,sizeof dist);
while(m--)
{
int a,b;
cin>>a>>b;
v[a].push_back(b);
}
bfs();
return 0;
}