leetcode924 尽量减少恶意软件的传播 题解

博客围绕LeetCode一道图传染问题展开。题目是给定图,部分点有传染性,同一联通块会被传染,可在初始有传染性点集中选一个使其无传染性,求选哪个点可使被传染点最少。题解是找符合条件且最大的联通块,代码最初用多次bfs,实际一次即可,最终通过。

读题读一年,题是个水题

题目描述

原地址
大致意思是给你一个图,然后一开始其中的一些点有传染性,跟其在同一联通块的点全部会被传染。我们把一开始有传染性的点的集合称之为 initial,然后在一开始的时候,你可以在 initial 里面选一个,让这个点变得没有传染性。现在问你选择哪个点可以使得被传染的点最少。

题解

其实很显然,当一个联通块里的点只有一个点在 initial 里面的时候,整个联通块就会避免被感染,然后这题的解法就是找一个符合条件且最大的联通块就行了。

代码

因为一开始尝试着写了写,结果弄的是一个要用好多遍 bfs 的做法,实际上只要 bfs 一次就好了。

class Solution {
public:
    int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
        const int N = graph.size();
        sort (initial.begin(), initial.end()); // 因为序号更小的点优先级更高,所以排序
        vector<int> vis(N, 0); // 记录被感染的点
        function<int(int)>bfs = [&](int x){
            for (int i = 0; i < N; i++) // 记得 init
                vis[i] = 0;
            queue<int> q;
            for (int i = 0; i < initial.size(); i++) // 把 initial 全部都搞进去,除了被枚举要去除传染性的点
                if (initial[i] != x)
                    q.push(initial[i]), vis[initial[i]] = 1;
            while (!q.empty()) // 把相连的点标记一下
            {
                int u = q.front();
                q.pop();
                for (int i = 0 ; i < N; i++)
                {
                    if (graph[u][i] == 0 || vis[i] == 1)
                        continue;
                    q.push(i), vis[i] = 1;
                }
            }
            int cnt = 0;
            for (int i = 0; i < N; i++) // 对没被感染的点进行计数
                if (!vis[i])
                    cnt++;
            return cnt;
        };
        int ans_node = -1, ans_cnt = -1;
        for (int i = 0; i < initial.size(); i++) // 看看哪个点更优
        {
            int cnt = bfs(initial[i]);
            if (cnt > ans_cnt)
                ans_node = initial[i], ans_cnt = cnt; 
        }
        return ans_node;
    }
};

结果

结果
有点丑陋,但是反正是过了






作者能力有限,如果有任何错误之处,还请各位指教。(~ ̄▽ ̄)~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值