Minimize Malware Spread

In a network of nodes, each node i is directly connected to another node j if and only if graph[i][j] = 1.

Some nodes initial are initially infected by malware.  Whenever two nodes are directly connected and at least one of those two nodes is infected by malware, both nodes will be infected by malware.  This spread of malware will continue until no more nodes can be infected in this manner.

Suppose M(initial) is the final number of nodes infected with malware in the entire network, after the spread of malware stops.

We will remove one node from the initial list.  Return the node that if removed, would minimize M(initial).  If multiple nodes could be removed to minimize M(initial), return such a node with the smallest index.

Note that if a node was removed from the initial list of infected nodes, it may still be infected later as a result of the malware spread.

Example 1:

Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]
Output: 0

思路:求最小,实际上是求最大,因为malware可能去掉以后重复感染,那么connect好graph之后,如果去掉两个链接的node其中一个实际上是没有任何作用的,因为还是会感染,那么只有root是只有1个值的malware,那个东西去掉之后才会有影响,那么题目求最小的M,也就是求最大的malware node他感染的数量最多,而且这个root只因为他一个人而感染。用个count函数count一下输入init之后感染的root次数就可以找出那种只有因为他一个人感染的connect component,把他移掉就可以了。当然count一下最大的那个node,从小到大,就是sort一下initial array就可以了。

class Solution {
    private class UnionFind {
        private int[] father;
        private int[] size;
        private int count;
        
        public UnionFind(int n) {
            this.father = new int[n+1];
            this.size = new int[n+1];
            for(int i = 0; i <= n; i++) {
                father[i] = i;
                size[i] = 1;
            }
            this.count = n;
        }
        
        public int find(int x) {
            int j = x;
            while(father[j] != j) {
                j = father[j];
            }
            //path compression;
            while(j != x) {
                int fx = father[x];
                father[x] = j;
                x = fx;
            }
            return j;
        }
        
        public void union(int a, int b) {
            int root_a = find(a);
            int root_b = find(b);
            if(root_a != root_b) {
                father[root_a] = root_b;
                size[root_b] += size[root_a];
                count--;
            }
        }
        
        public int[] getSizeArray() {
            return this.size;
        }
    }
    
    public int minMalwareSpread(int[][] graph, int[] initial) {
        int n = graph.length;
        UnionFind uf = new UnionFind(n);
        for(int i = 0; i < n; i++) {
            for(int j = i+1; j < n; j++) {
                if(graph[i][j] == 1) {
                    uf.union(i, j);
                }
            }
        }
        
        int[] size = uf.getSizeArray();
        int[] malware = new int[n];
        for(Integer i: initial) {
            malware[uf.find(i)]++;
        }
        Arrays.sort(initial);
        
        int maxweight = 0;
        int index = initial[0];
       
        for(Integer i: initial) {
            if(malware[uf.find(i)] == 1) {
                int weight = size[uf.find(i)];
                if(weight > maxweight) {
                    maxweight = weight;
                    index = i;
                }
            }
        }
        return index;
    }
}
发布了710 篇原创文章 · 获赞 13 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/u013325815/article/details/105342512