You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

##AcWing 847. 图中点的层次

一、题目描述

给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。

所有边的长度都是 1,点的编号为 1n

请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 1

输入格式 第一行包含两个整数 nm

接下来 m 行,每行包含两个整数 ab,表示存在一条从 a 走到 b 的长度为 1 的边。

输出格式 输出一个整数,表示 1 号点到 n 号点的最短距离。

数据范围 1≤n,m≤10^5

输入样例:

4 5
1 2
2 3
3 4
1 3
1 4

输出样例:

1

二、思考与总结

1、本题是图的存储+BFS的结合

2、图的存储用邻接表

3、图的权值是1的时候,重边和环不用考虑

4、所有长度都是1,表示可以用bfs来求最短路,否则应该用迪杰斯特拉等算法来求图中的最短路径。

5、bfs需要记录的是出发点到当前点的距离,就是d数组,每次d要增加1

6、一定要注意数组的初始化 (1) memset(h,-1,sizeof h); //数组的整体初始化为-1这是链表结束循环的边界缺少会TLE (2) memset(d,-1,sizeof d); //表示没有走过。

三、实现代码

#include <bits/stdc++.h>

using namespace std;
const int N = 100010, M = N << 1;
int n, m;

int h[N], e[M], ne[M], idx;
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int d[N];

int bfs() {
    queue<int> q;
    q.push(1);
    d[1] = 0;
    while (q.size()) {
        auto u = q.front();
        q.pop();
        for (int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if (d[j] == -1) {
                d[j] = d[u] + 1;
                q.push(j);
            }
        }
    }
    return d[n];
}

int main() {
    memset(h, -1, sizeof h);
    memset(d, -1, sizeof d);
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int a, b;
        cin >> a >> b;
        add(a, b);
    }
    cout << bfs() << endl;
    return 0;
}