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.
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.
Input: Network information as a list of lists with integers.
Output: The total time of taken to capture the network as an integer.
原题链接: http://www.checkio.org/mission/network-attack/
题目大义: 有N台电脑, 给定邻接矩阵, 每个电脑有被感染的时间, 计算感染整个网络电脑的时间
思路: 贪心算法, 每次感染距离0号电脑最近的电脑(时间最短), 最后感染的电脑时间即为网络感染时间
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
Network Attack