题解 | #MT18 重要节点#(广度优先搜索+图+哈希表)

重要节点

https://www.nowcoder.com/practice/56901e8163d141108ec59fb603bffb4f

解题思路

1.使用广度优先搜索分别计算当前节点的S值和T值,S值即为以当前节点i为起始点所有能访问的节点数,T值则为对所有节点执行广度优先搜索,当前节点i被访问的次数;

代码

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n, m;
    while(cin >> n >> m){
        int u, v;
        unordered_map<int, unordered_set<int>> f; //第二维使用set的原因在于输入中可能存在重边
        for(int i = 0; i < m; i++){
            cin >> u >> v;
            if(u == v) continue; //过滤掉自环
            f[u].insert(v); //u到v的有向边
        }
        vector<int> S(n + 1), T(n + 1); //当前节点能到的点集合大小及能到当前节点的点的集合大小
        for(int i = 1; i <= n; i++){
            //if(f.count(i) == 0) continue; //从当前节点出发能到的节点集合为0 S为0(不算自己本身)
            queue<int> q;
            vector<bool> isVisited(n + 1); //防止有环
            q.push(i);
            isVisited[i] = true;
            int cnt = 0; //统计节点i能到的点的个数 S值
            int curSize = 0;
            while(!q.empty()){
                curSize = q.size();
                cnt += curSize;
                for(int j = 0; j < curSize; j++){
                    int node = q.front();
                    T[node]++; //能到node节点的集合大小加1
                    q.pop();
                    if(f.count(node) == 0) continue;
                    for(auto& e : f[node]){
                        if(isVisited[e]) continue;
                        q.push(e);
                        isVisited[e] = true;
                    }
                }
            }
            S[i] = cnt;
        }
        int ans = 0;
        for(int i = 1; i <= n; i++){
            if(T[i] > S[i]) ans++;
        }
        cout << ans << endl;
    }
    return 0;
}
全部评论

相关推荐

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