Network Attack

Network Attack

Nicola regularly inspects the local networks for security issues. He uses a smart and aggressive program which takes control of computers on the network. This program attacks all connected computers simultaneously, then uses the captured computers for further attacks. Nicola started the virus program in the first computer and took note of the time it took to completely capture the network. We can help him improve his process by modeling and improving his inspections.node

We are given information about the connections in the network and the security level for each computer. Security level is the time (in minutes) that is required for the virus to capture a machine. Capture time is not related to the number of infected computers attacking the machine. Infection start from the 0th computer (which is already infected). Connections in the network are undirected. Security levels are not equal to zero.算法

Information about a network is represented as a matrix NxN size, where N is a number of computers. If ith computer connected with jth computer, then matrix[i][j] == matrix[j][i] == 1, else 0. Security levels are placed in the main matrix diagonal, so matrix[i][i] is the security level for the ith computer.網絡

You should calculate how much time is required to capture the whole network in minutes.app

Input: Network information as a list of lists with integers.ui

Output: The total time of taken to capture the network as an integer.spa

原題連接: http://www.checkio.org/mission/network-attack/code

題目大義: 有N臺電腦, 給定鄰接矩陣, 每一個電腦有被感染的時間, 計算感染整個網絡電腦的時間orm

思路: 貪心算法, 每次感染距離0號電腦最近的電腦(時間最短), 最後感染的電腦時間即爲網絡感染時間blog

 1 def capture(matrix):
 2     infected_time = {0:0} #key is the computer id and value is the 0 computer to id computer's minutes
 3     infected_id = set() #store the infected computers id
 4 
 5     rel = 0
 6 
 7     while infected_time:
 8         #select the minimum minutes computer
 9         top_computer = min(infected_time.items(), key=lambda d:d[1])
10 
11         rel = top_computer[1]
12 
13         infected_id.add(top_computer[0])
14 
15         #find the adjacent computers and update the minutes
16         for c_id, connect in enumerate(matrix[top_computer[0]]):
17             if connect and c_id != top_computer[0] and c_id not in infected_id:
18                 tmp_minutes = infected_time[top_computer[0]] + matrix[c_id][c_id]
19                 if infected_time.get(c_id) == None or infected_time[c_id] > tmp_minutes:
20                     infected_time[c_id] = tmp_minutes
21 
22         #pop the top_computer
23         infected_time.pop(top_computer[0])
24 
25     return rel

在思路成熟以後, 實際上我也考慮過優先隊列的實現, 無奈搜網上的代碼都感受到比較複雜, 然而觀摩Sim0000的代碼後, 受益頗多隊列

 1 from heapq import heappush, heappop
 2  
 3 def capture(matrix):
 4     n = len(matrix)
 5     q = [(0,0)] # time, node
 6     tmin = {}   # dictionary of min time for each node
 7  
 8     while(q):
 9         time, node = heappop(q)
10         if node in tmin: continue # already visited
11         tmin[node] = time         # first visit means min time of node
12         if len(tmin) == n: break
13         for i, connect in enumerate(matrix[node]):
14             if i != node and connect and i not in tmin:
15                 heappush(q, (time + matrix[i][i], i))
16     return max(tmin.values())
17  
18     # use heapq as priority queue
19     # BFS search
相關文章
相關標籤/搜索