题解 | #MT16 公交车#(模拟建图+广度优先搜索)

公交车

https://www.nowcoder.com/practice/630816b6884f4ad49590b6c07bab40fc

解题思路

1.同条路线的站点互通只需要一辆公交车即可,建立虚拟节点连接同条公交路线的各个站点,以此建图;每条公交路线的虚拟节点不一样,且不能与实际节点重合,虚拟节点编号可考虑在一个基础值之上递增;从source到target的路径数除以2即为最小代价;

代码

#include <bits/stdc++.h>

using namespace std;

int bfs(unordered_map<int, vector<int>>& g, vector<bool>& isVisited, int t){ //返回最小代价,不能到达返回-1
    queue<int> q;
    q.push(1);
    isVisited[1] = true;
    int curSize, step = -1;
    while(!q.empty()){
        curSize = q.size();
        step++;
        for(int i = 0; i < curSize; i++){
            int node = q.front();
            if(node == t) return step / 2; //注意这里需要除以2
            q.pop();
            for(auto& e : g[node]){
                if(isVisited[e]) continue;
                q.push(e);
                isVisited[e] = true;
            }
        }
    }
    return -1;
}

int main(){
    int n, m;
    while(cin >> n >> m){
        unordered_map<int, vector<int>> g;
        vector<bool> isVisited(n + m + 1); //注意还有虚拟节点(否则数组越界)
        int t;
        for(int i = 1; i <= m; i++){ //每个班车路线共用一个虚拟节点n+i
            cin >> t;
            int v;
            for(int j = 0; j < t; j++){
                cin >> v;
                if(v < 1 || v > n) continue; //当站点不合法时,不加入图中
                g[n + i].push_back(v);
                g[v].push_back(n + i);
            }
        }
        int minCost = bfs(g, isVisited, n);
        cout << minCost << endl;
    }
    return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务