十二、图的遍历--(4)最短路径简化版

摘自计蒜客:http://www.jisuanke.com/course/35/7317

小明外出游玩,景区一共有 NN 个地方可以玩耍,编号从 11 到 NN,并且知道了小明现在所在景点的编号 CC,以及 MM 条路径。现在求小明到每个地方分别需要经过多少个地方?

输入格式:

第一行输入三个正整数 N, M, CN,M,C。代表蒜头君想去 NN 个地方,有 MM 条路径,蒜头君在编号为 CC 的地方。1 \leq N, C \leq 10001N,C10001 \leq C \leq N1CN1 \leq M \leq 100001M10000

保证没有重复边,且图中所有点互相连通。

输出格式:

输出 NN 行,按编号从小到大,输出结果。第 ii行表示蒜头君到编号为 ii 的地方,需要经过多少个地方。

样例1

输入:

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

输出:

1
0
1
1
2
代码实现(一种解法,应该有更好的解法):

#include <iostream>

#include <vector>
#include <cstring>
#include <queue>

using namespace std;

class Graph {
private:
    int n;
    bool *visited;
    vector<int> *edges;
    int *minlen;
public:
    Graph(int input_n) {
        n = input_n;
        edges = new vector<int>[n];
        visited = new bool[n];
        minlen = new int[n];
        memset(visited, 0, n);
        memset(minlen, 0, n*sizeof(int));
    }

    ~Graph() {
        delete[] edges;
        delete[] visited;
        delete[] minlen;
    }

    void insert(int x, int y) {
        edges[x].push_back(y);
        edges[y].push_back(x);
    }

    void bfs(int start_vertex) {
        int len = 1,last,nlast;
        queue<int> bfs_queue;
        bfs_queue.push(start_vertex);
        visited[start_vertex] = true;
        last = start_vertex;
        while (!bfs_queue.empty()) {
            int vertex = bfs_queue.front();
            for (int adj_vertex:edges[vertex]) {
                if (!visited[adj_vertex]) {
                    visited[adj_vertex] = true;
                    bfs_queue.push(adj_vertex);
                    nlast = adj_vertex;
                    minlen[adj_vertex] = len;
                }
            }
            bfs_queue.pop();
            
            if(vertex == last) {
                last = nlast;
                len++;
            }
        }
        for(int i=1; i<n; i++) {
            cout << minlen[i] << endl;
        }
    }
};

int main() {
    int n, m, k;
    cin >> n >> m >> k;
    Graph g(n+1);
    for (int i = 0; i < m; ++i) {
        int x, y;
        cin >> x >> y;
        g.insert(x, y);
    }
    g.bfs(k);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值