-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathMinimize Malware Spread II.java
94 lines (86 loc) · 2.99 KB
/
Minimize Malware Spread II.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
class Solution {
int[] parent;
int[] size;
public int find(int x){
if(parent[x]==x) return x;
int f = find(parent[x]);
parent[x] = f;
return f;
}
void merge(int x, int y){
if(size[x]>size[y]){
parent[y] = x;
size[x] += size[y];
}else{
parent[x] =y;
size[y] +=size[x];
}
}
public int minMalwareSpread(int[][] graph, int[] initial) {
int n =graph.length;
parent = new int[n];
size= new int[n];
// putting initially infected nodes in hashset to ignore them while making graph
HashSet<Integer> hs = new HashSet<>();
for(int a : initial){
hs.add(a);
}
//initializing Parent for DSU
for(int i=0;i<parent.length;i++){
parent[i] = i;
size[i]=1;
}
//constructing groups DSU
for(int i=0;i<graph.length;i++){
for(int j=0;j<graph[0].length;j++){
if(graph[i][j]==1 && !hs.contains(i) && !hs.contains(j)){
int p1 = find(i);
int p2 = find(j);
if(p1!=p2){
merge(p1,p2); //merging if they are not already
}
}
}
}
//Storing initial Nodes vs parents of connected node...if there are multiple edge to same component then we will get the same parent twice ...so we will take hashset for that purpose.
HashMap<Integer,HashSet<Integer>> map = new HashMap<>();
//We need to ensure increase the count whenever a parent is influenced by initial Nodes...because if it influenced by more than one infectious node then it would still remain infectious.
int[] infected = new int[n];
for(int e: initial){
map.put(e,new HashSet<>());
for(int j=0;j<n;j++){
// in adjaceny graph[i][i] is always one so we will ignore that
if(!hs.contains(j) && e!=j && graph[e][j]==1){
int p = find(j);
if(!map.get(e).contains(p)){
map.get(e).add(p);
infected[p]++;
}
}
}
}
int max = -1;
int ans =-1;
for(int e:initial){
HashSet<Integer> par = map.get(e);
int total =0;
for(int p: par){
if(infected[p]==1){ //add to total only if influenced by only one infectious node.
total+=size[p];
}
}
if(total>=max){
if(max==total){
ans = Math.min(ans,e);
}else{
ans =e;
}
max =total;
}
}
if(ans!=-1) return ans;
//for returining smallest element.
Arrays.sort(initial);
return initial[0];
}
}