九章算法 | 京东面试题:尽量减少恶意软件的传播II

描述

在节点网络中,只有当graph[i][j] = 1 时,每个节点i能够直接连接到另一个节点j。

一些节点initial最初被恶意软件感染。只要两个节点直接连接,且其中至少一个节点受到恶意软件的感染,那么两个节点都将被恶意软件感染。这种恶意软件的传播将继续,直到没有更多的节点可以被这种方式感染。

假设 M(initial) 是在恶意软件停止传播之后,整个网络中感染恶意软件的最终节点数。

我们可以从初始列表中删除一个节点,并完全移除该节点以及从该节点到任何其他节点的任何连接。如果移除这一节点将最小化 M(initial), 则返回该节点。如果有多个节点满足条件,就返回索引最小的节点。

1 < graph.length = graph[0].length <= 300 
0 <= graph[i][j] == graph[j][i] <= 1 
graph[i][i] = 1 
1 <= initial.length < graph.length 
0 <= initial[i] < graph.length 

在线评测地址:

LintCode 领扣

样例1

输入:graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1] 
输出:0 
解释:移除0然后只有1被感染。 

样例2

输入:graph = [[1,1,0],[1,1,1],[0,1,1]], initial = [0,1] 
输出:1 
解释:移除1然后只有0被感染。 

考点

  • 图论
  • 搜索

题解

从受感染的顶点起始顶点编号开始dfs染色直到找不到另一个受感染的顶点如果当前顶点已具有其他颜色将其排除设置为-2)。答案是出现最多次的颜色对应的受感染的顶点或受感染的最小顶点如果所有顶点至少染色2次)。 
class Solution { 
public: 
    vector<int> col;     
 
    void dfs(vector<vector<int>>& g,unordered_set<int> &hs,int v,int c) { 
        col[v] = col[v] == -1 ? c:-2; 
        for(int i = 0;i < g.size();++i){ 
            if(g[v][i] && !hs.count(i) && col[i] != c && col[i] != -2) { 
                dfs(g,hs,i,c); 
            } 
        } 
    } 
 
    int minMalwareSpread(vector<vector<int>>& g, vector<int>& in) { 
        unordered_map<int,int> hm;         
        unordered_set<int> hs(in.begin(),in.end()); 
        int n = g.size(), res, mx=0; 
        col.resize(n,-1); 
        for(auto v:in) dfs(g,hs,v,v); 
        for(auto v:col) { 
            if(v >= 0) { 
                if(++hm[v] > mx) { 
                    res = v; 
                    mx = hm[v]; 
                } 
                else if(hm[v] == mx) { 
                    res = min(res,v); 
                } 
            } 
        } 
        if(hm.empty()) {  
            return *min_element(in.begin(),in.end()); 
        } 
        return res; 
    } 
}; 

更多题解参考:九章算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值