题目传送门

一、思考与总结

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); //表示没有走过。

二、STL队列

#include <bits/stdc++.h>

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

//h[N]表示有N条单链表的头,e[M]代表每个节点的值,ne[M]代表每个节点的下一个节点号
int h[N], e[N << 1], ne[N << 1], idx;
int d[N];//距离
queue<int> q;

//树和图的存储
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int bfs() {
    //1号结点入队列
    q.push(1);
    //1号结点到自己的距离是0
    d[1] = 0;
    //bfs
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        //遍历链表
        for (int i = h[u]; i != -1; i = ne[i]) {
            int j = e[i];
            if (d[j] == -1) { //没走过
                d[j] = d[u] + 1;
                q.push(j);
            }
        }
    }
    //1号结点到n号结点的最短距离
    return d[n];
}

int main() {
    //输入优化
    ios::sync_with_stdio(false);
    //n个结点,m条边
    cin >> n >> m;

    //初始化为-1,头节点写成-1
    memset(h, -1, sizeof h);

    //设置所有距离为-1
    memset(d, -1, sizeof d);

    //读入数据
    for (int i = 1; i <= m; i++) {
        int a, b;
        cin >> a >> b;
        add(a, b);
    }
    //输出
    cout << bfs() << endl;
    return 0;
}

三、数组模拟队列

#include <bits/stdc++.h>

using namespace std;
const int N = 100010;
int n, m;
//h[N]表示有N条单链表的头,e[M]代表每个节点的值,ne[M]代表每个节点的下一个节点号
int h[N], e[N << 1], ne[N << 1], idx;
int d[N];//距离
int q[N], hh, tt = -1;

//树和图的存储
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int bfs() {
    q[++tt] = 1;
    d[1] = 0; //第一节点的距离是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;
                q[++tt] = j;
            }
        }
    }
    return d[n];
}

int main() {
    //输入优化
    ios::sync_with_stdio(false);
    //n个结点,m条边
    cin >> n >> m;
    //初始化为-1,头节点写成-1
    memset(h, -1, sizeof h);
    //设置所有距离为-1
    memset(d, -1, sizeof d);

    //读入数据
    for (int i = 1; i <= m; i++) {
        int a, b;
        cin >> a >> b;
        add(a, b);
    }
    //输出
    cout << bfs() << endl;
    return 0;
}

相关文章:

  • 2022-01-28
  • 2021-05-01
  • 2021-09-11
  • 2021-04-01
  • 2021-11-18
  • 2022-12-23
  • 2022-12-23
  • 2021-11-29
猜你喜欢
  • 2022-12-23
  • 2022-02-25
  • 2021-08-15
  • 2022-12-23
  • 2021-11-21
  • 2022-12-23
  • 2021-10-17
相关资源
相似解决方案