★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-ynzeyqdo-me.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
(This problem is the same as Minimize Malware Spread, with the differences bolded.)node
In a network of nodes, each node i
is directly connected to another node j
if and only if graph[i][j] = 1
.git
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.github
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, completely removing it and any connections from this node to any other node. 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.網絡
Example 1:ui
Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1] Output: 0
Example 2:this
Input: graph = [[1,1,0],[1,1,1],[0,1,1]], initial = [0,1] Output: 1
Example 3:spa
Input: graph = [[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]], initial = [0,1] Output: 1
Note:code
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
(這個問題與 儘可能減小惡意軟件的傳播 是同樣的,不一樣之處用粗體表示。)
在節點網絡中,只有當 graph[i][j] = 1
時,每一個節點 i
可以直接鏈接到另外一個節點 j
。
一些節點 initial
最初被惡意軟件感染。只要兩個節點直接鏈接,且其中至少一個節點受到惡意軟件的感染,那麼兩個節點都將被惡意軟件感染。這種惡意軟件的傳播將繼續,直到沒有更多的節點能夠被這種方式感染。
假設 M(initial)
是在惡意軟件中止傳播以後,整個網絡中感染惡意軟件的最終節點數。
咱們能夠從初始列表中刪除一個節點,並徹底移除該節點以及從該節點到任何其餘節點的任何鏈接。若是移除這一節點將最小化 M(initial)
, 則返回該節點。若是有多個節點知足條件,就返回索引最小的節點。
示例 1:
輸出:graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1] 輸入:0
示例 2:
輸入:graph = [[1,1,0],[1,1,1],[0,1,1]], initial = [0,1] 輸出:1
示例 3:
輸入:graph = [[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]], initial = [0,1] 輸出:1
提示:
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
1058ms
1 class Solution { 2 func minMalwareSpread(_ graph: [[Int]], _ initial: [Int]) -> Int { 3 var n:Int = graph.count 4 var arr = initial.sorted(by: <) 5 6 var min:Int = 99999999 7 var arg:Int = -1 8 for i in arr 9 { 10 var linf:[Bool] = [Bool](repeating: false,count: n) 11 var ds:DJSet = DJSet(n) 12 for j in 0..<n 13 { 14 for k in (j + 1)..<n 15 { 16 if j == i || k == i {continue} 17 if graph[j][k] == 1 {ds.union(j,k)} 18 19 } 20 } 21 for v in arr 22 { 23 if v != i 24 { 25 linf[ds.root(v)] = true 26 } 27 } 28 var g:Int = 0 29 for j in 0..<n 30 { 31 if linf[ds.root(j)] 32 { 33 g += 1 34 } 35 } 36 if g < min 37 { 38 min = g 39 arg = i 40 } 41 42 } 43 return arg 44 } 45 } 46 class DJSet 47 { 48 var upper:[Int] = [Int]() 49 50 init(_ n:Int) 51 { 52 self.upper = [Int](repeating: -1,count: n) 53 } 54 55 func root(_ x:Int) -> Int 56 { 57 if upper[x] < 0 58 { 59 return x 60 } 61 else 62 { 63 upper[x] = root(upper[x]) 64 } 65 return upper[x] 66 } 67 68 func equiv(_ x:Int,_ y:Int) -> Bool 69 { 70 return root(x) == root(y) 71 } 72 73 func union(_ x:Int,_ y:Int) -> Bool 74 { 75 var x = root(x) 76 var y = root(y) 77 if x != y 78 { 79 if upper[y] < upper[x] 80 { 81 var d:Int = x 82 x = y 83 y = d 84 } 85 upper[x] += upper[y] 86 upper[y] = x 87 } 88 return x == y 89 } 90 91 func count() -> Int 92 { 93 var ct:Int = 0 94 for u in upper 95 { 96 if u < 0 97 { 98 ct += 1 99 } 100 } 101 return ct 102 } 103 }
2020ms
1 class Solution { 2 var visited: Set<Int> = Set() 3 var initial: Set<Int> = Set() 4 var graph : [[Int]] = [] 5 6 func traverse(_ pos: Int) -> Int { 7 if visited.contains(pos) { 8 return 0 9 } 10 var result = 1 11 visited.insert(pos) 12 for i in 0..<graph.count { 13 if i != pos && graph[pos][i] == 1 { 14 if !visited.contains(i) { 15 result += traverse(i) 16 } 17 } 18 } 19 return result 20 } 21 22 func countComponent(_ start: Int) -> Int { 23 return traverse(start) 24 } 25 26 func minMalwareSpread(_ graph: [[Int]], _ initial: [Int]) -> Int { 27 self.graph = graph 28 self.initial = Set<Int>(initial) 29 30 var mincnt = graph.count 31 var mini = -1 32 33 for removed in initial.sorted() { 34 visited = Set() 35 visited.insert(removed) 36 var n = 0 37 for x in initial { 38 n += countComponent(x) 39 } 40 if n < mincnt { 41 mincnt = n 42 mini = removed 43 } 44 } 45 46 return mini 47 } 48 }
2696ms
1 class Solution { 2 func minMalwareSpread(_ graph: [[Int]], _ initial: [Int]) -> Int { 3 var n:Int = graph.count 4 var arr = initial.sorted(by: <) 5 6 var min:Int = 99999999 7 var arg:Int = -1 8 for i in arr 9 { 10 var linf:[Bool] = [Bool](repeating: false,count: n) 11 var ds:DJSet = DJSet(n) 12 for j in 0..<n 13 { 14 for k in (j + 1)..<n 15 { 16 if j == i || k == i {continue} 17 if graph[j][k] == 1 {ds.union(j,k)} 18 19 } 20 } 21 for v in arr 22 { 23 if v != i 24 { 25 linf[ds.root(v)] = true 26 } 27 } 28 var g:Int = 0 29 for j in 0..<n 30 { 31 if linf[ds.root(j)] 32 { 33 g += 1 34 } 35 } 36 if g < min 37 { 38 min = g 39 arg = i 40 } 41 42 } 43 return arg 44 } 45 } 46 class DJSet 47 { 48 var upper:[Int] = [Int]() 49 50 init(_ n:Int) 51 { 52 self.upper = [Int](repeating: -1,count: n) 53 } 54 55 func root(_ x:Int) -> Int 56 { 57 if upper[x] < 0 58 { 59 return x 60 } 61 else 62 { 63 upper[x] = root(upper[x]) 64 } 65 return upper[x] 66 } 67 68 func equiv(_ x:Int,_ y:Int) -> Bool 69 { 70 return root(x) == root(y) 71 } 72 73 func union(_ x:Int,_ y:Int) -> Bool 74 { 75 var x = root(x) 76 var y = root(y) 77 if x != y 78 { 79 if upper[y] < upper[x] 80 { 81 var d:Int = x 82 x = y 83 y = d 84 } 85 upper[x] += upper[y] 86 upper[y] = x 87 } 88 return x == y 89 } 90 91 func count() -> Int 92 { 93 var ct:Int = 0 94 for u in upper 95 { 96 if u < 0 97 { 98 ct += 1 99 } 100 } 101 return ct 102 } 103 }