Java BFS 题解 | #病毒传播#

病毒传播

http://www.nowcoder.com/practice/3b6060942397444cb0fe5846e230f6d9

import java.util.*;

public class Main {
    // 声明变量
    static int n, sz, m, k, t;
    static Set<Integer>[] table;
    static boolean[] infected;

    private static void dealWithInput() {
        Scanner sc = new Scanner(System.in);
        sz = (n = sc.nextInt()) + 1; // 使用节点的逻辑索引
        m = sc.nextInt();
        // 初始化图
        infected = new boolean[sz];
        table = (Set<Integer>[]) new HashSet[sz]; // 边去重
        for (int xl = 1; xl < sz; xl++) table[xl] = new HashSet<Integer>();
        // 读取接下来数据
        for (int i = 0; i < m; i++) {
            int u = sc.nextInt(), v = sc.nextInt();
            if(u != v) {
                table[u].add(v);
                table[v].add(u);
            }
        }
        k = sc.nextInt();
        t = sc.nextInt();
        for(int i = 0; i < k; i++) {
            infected[sc.nextInt()] = true; // 也可以使用 set
        }
    }

    // 遍历感染集中每一个结点,BFS 访问。若半径范围内的结点出现未感染,则返回 false,
    private static List<Integer> solution() {
        List<Integer> ans = new ArrayList<>();
        for (int node = 1; node < sz; node++) {
            if (infected[node] && check(node))
                ans.add(node);
        }
        return ans;
    }

    private static boolean check(int node) { // 检查结点是否符合传染源的条件
        // 需要队列、vis[]
        Queue<Integer> queue = new LinkedList<>();
        boolean[] vis = new boolean[sz];

        queue.offer(node);
        vis[node] = true;
        int setCnt = 0, sz;
        // 需要出队 1 + t 次。最后一次的入队不做处理
        for (int nout = 0; nout < t + 1 && (sz = queue.size()) > 0; nout++) {
            while (sz-- > 0) {
                int poll = queue.poll();
                // 进行判断
                if (!infected[poll]) return false;
                ++setCnt; // 表示被传染结点的个数

                // 加入相邻结点
                for (int next : table[poll]) {
                    if (!vis[next]) {
                        queue.offer(next);
                        vis[next] = true; // 入队时标记为已访问
                    }
                }
            }
        }
        
        return setCnt == k;
    }

    public static void main(String[] args) {
        dealWithInput();
        List<Integer> ans = solution();
        if (ans.size() > 0) {
            System.out.print(ans.get(0));
            for (int i = 1; i < ans.size(); i++) {
                System.out.printf(" " + ans.get(i));
            }
        } else {
            System.out.println(-1);
        }
    }
}

全部评论

相关推荐

02-10 21:39
Java
点赞 评论 收藏
分享
一天代码十万三:实习东西太少了,而且体现不出你业务,3个月不可能就这点产出吧,建议实习多写点,玩具项目面试官都不感兴趣的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务