Minimize Malware Spread II - Solution
Code
# Code
```java []
class Solution {
    public int minMalwareSpread(int[][] graph, int[] initial) {
        int n = graph.length;

        // Tarjan's Algorithm Data Structures
        int[] discoveryTime = new int[n];
        int[] low = new int[n];
        int[] malwareSpreadCount = new int[n];
        int[] parent = new int[n];
        AtomicInteger time = new AtomicInteger();

        Arrays.fill(discoveryTime, -1);
        Arrays.fill(low, -1);
        Arrays.fill(parent, -1);

        boolean[] isInfected = new boolean[n];

        for (int node : initial) {
            isInfected[node] = true;
        }

        int nodeToRemove = initial[0];
        int maxSavedNodes = 0;

        for (int node : initial) {
            if (discoveryTime[node] == -1) {
                dfs(graph, node, parent, time, discoveryTime, low, isInfected, malwareSpreadCount);
            }

            if (malwareSpreadCount[node] > maxSavedNodes
                    || (malwareSpreadCount[node] == maxSavedNodes && node < nodeToRemove)) {
                maxSavedNodes = malwareSpreadCount[node];
                nodeToRemove = node;
            }
        }
        return nodeToRemove;
    }

    private int dfs(int[][] graph, int currentNode, int[] parent, AtomicInteger currentTime, int[] discoveryTime, int[] low,
            boolean[] isInfected, int[] malwareSpreadCount) {
        discoveryTime[currentNode] = currentTime.incrementAndGet();
        low[currentNode] = discoveryTime[currentNode];

        boolean isMalwareSpread = isInfected[currentNode];
        int componentSize = 1;

        for (int neighbor = 0; neighbor < graph[currentNode].length; neighbor++) {
            if (graph[currentNode][neighbor] == 1) {
                if (discoveryTime[neighbor] == -1) {
                    parent[neighbor] = currentNode;
                    int subTreeSize = dfs(graph, neighbor, parent, currentTime, discoveryTime, low,
                            isInfected, malwareSpreadCount);

                    if (subTreeSize == 0) {
                        isMalwareSpread = true;
                    } else {
                        componentSize += subTreeSize;
                    }

                    if (low[neighbor] >= discoveryTime[currentNode]) {
                        malwareSpreadCount[currentNode] += subTreeSize;
                    }
                    low[currentNode] = Math.min(low[currentNode], low[neighbor]);
                } else if (neighbor != parent[currentNode]) {
                    low[currentNode] = Math.min(low[currentNode], discoveryTime[neighbor]);
                }
            }
        }
        return isMalwareSpread ? 0 : componentSize;
    }
}
```
['Array', 'Depth-First Search', 'Graph', 'Java']