恶意代码 - Malicious Code - BFS & 01背包
作者:互联网
恶意代码
(测试用例总数:X 个,1 秒 (C/C++),1.5 秒 (JAVA)/内存要求:256 M,Stack 1 M)
S 公司的网络管理员琳收到了一通紧急来电。来电告知公司内部设备连接的网络中发现了恶意代码,必须马上采取相应措施。
S 公司有 N 台设备,通过 M 根线路连接,所以如果其中一台设备感染恶意代码,其他设备也会通过连接网络感染上恶意代码。目前,已有 K 台设备感染恶意代码,代码扩散危机迫在眉睫。受感染的设备需要立即处理,但在目前的情况下,最多只能处理三台设备。
保受感染的设备数量尽可能少的情况下,帮助琳确定要处理的设备,同时求出未受感染设备的最大数量。
如上图所示,有 10 台设备连接,编号为 2、4、5、8 的设备感染了恶意代码,处理编号为 2、4、5 的设备,就可以保护 7 台设备,这是能实现的不受感染设备的最大数量。
[限制条件]
1.设备数量N为5以上,100,000以下的整数。
2.线路数量 M 为1以上,300,000以下的整数。
3.受感染的设备数K为3以上,N以下的整数。
4.受感染的设备即使经过处理后,仍然可能会再次被其他受感染的设备感染。
[输入]
首先给出测试用例数量T,随后给出T个测试用例。在每个测试用例的第一行,给定设备数量 N,线路数量 M、感染恶意代码的设备数量 K,以空格分隔。从第二行到第M行,每行给定一条线路两端连接的设备 A 和 B 的编号,以空格分隔。在第 M+2 行,给定 K 台感染恶意代码的设备编号,以空格分隔。
[输出]
每行输出一个测试用例。首先,输出“#x”(其中 x 表示测试用例编号,从 1 开始),加一个空格,最后输出处理三台设备后,恶性代码扩散时,能实现的未感染设备的最大数量。
[输入和输出示例]
(输入)
2
10 9 4
1 2
2 3
2 5
4 5
4 6
5 6
5 7
8 9
9 10
2 4 5 8
10 9 5
1 2
2 3
2 5
4 5
4 6
5 6
5 7
8 9
9 10
2 4 5 6 8
(输出)
#1 7
#2 3
思路分析:
bfs遍历算出每个连通图中感染病毒的结点数及连通图总结点数,感染病毒结点数>3 则丢弃,<=3存放在List集合中
根据题意最多可修复的电脑数是3个,可以理解为01背包中已知最大容量,将感染的电脑看做一个整体的物品,物品权重wi即可修复的电脑数量,物品价值即连通图节点数
套用01背包工时dp[j] = max(dp[j-w[i]]+vi,dp[j]),最后算出的dp[3] 则为最后的结果
package graph; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Queue; import java.util.StringTokenizer; /** * 恶意代码思路分析: * bfs+01背包 * bfs遍历算出每个连通图中感染病毒的结点数及连通图总结点数,感染病毒结点数>3 则丢弃,<=3存放在List集合中 * 根据题意最多可修复的电脑数是3个,可以理解为01背包中已知最大容量,将感染的电脑看做一个整体的物品,物品权重wi即可修复的电脑数量,物品价值即连通图节点数 * 套用01背包工时dp[j] = max(dp[j-w[i]]+vi,dp[j]),最后算出的dp[3] 则为最后的结果 * * @author XA-GDD * */ public class EQ_MaliciousCode_0712 { static int T,N,M,K; static int _max_Nval = 100000; static ArrayList<Integer> [] adjList = new ArrayList[_max_Nval+1]; static boolean [] badNode = new boolean[_max_Nval+1]; static boolean [] visited = new boolean[_max_Nval+1]; static ArrayList<int []> list = new ArrayList<int[]>(); static int [] dp = new int[4]; static int nodeCnt; public static void main(String[] args) throws IOException { System.setIn(new FileInputStream("D:\\workspace\\sw_pro\\test_case\\sample_input_0712.txt")); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); T = Integer.parseInt(st.nextToken()); for(int testCase = 1; testCase<= T;testCase++) { st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); K = Integer.parseInt(st.nextToken()); for(int i=1;i<=N;i++) { adjList[i] = new ArrayList<Integer>(); } // Arrays.fill(adjList, new ArrayList<Integer>()); 初始化不可用此代码 Arrays.fill(badNode, false); Arrays.fill(visited, false); list.clear(); Arrays.fill(dp, 0); nodeCnt = 0; for(int i=0;i<M;i++) { st = new StringTokenizer(br.readLine()); int s = Integer.parseInt(st.nextToken()); int e = Integer.parseInt(st.nextToken()); adjList[s].add(e); adjList[e].add(s); } st = new StringTokenizer(br.readLine()); for(int i=0;i<K;i++) { int node = Integer.parseInt(st.nextToken()); badNode[node] = true; } for(int i=1;i<=N;i++) { if(nodeCnt==N) { break; } if(!visited[i]) { bfs(i); } } getResult(); System.out.printf("#%d %d\n",testCase,dp[3]); } } //0-1背包 static void getResult() { for(int i=0;i<list.size();i++) { int wi = list.get(i)[1]; int vi = list.get(i)[0]; for(int j=3;j>=wi;j--) { dp[j] = Math.max(dp[j], dp[j-wi]+vi); } } } //bfs遍历算出每个连通图中感染病毒的结点数及连通图总结点数,感染病毒结点数>3 则丢弃,<=3存放在List集合中 static void bfs(int s) { Queue<Integer> queue = new ArrayDeque<Integer>(); queue.add(s); visited[s] = true; int nodeTotCnt = 0; //连通图的节点个数 int badNodeCnt = 0; //坏节点个数 while(!queue.isEmpty()) { int curr = queue.poll(); nodeTotCnt++; nodeCnt++; if(badNode[curr]) { badNodeCnt++; } for(int i=0;i<adjList[curr].size();i++) { int next = adjList[curr].get(i); if(!visited[next]) { queue.add(next); visited[next] = true; } } } if(badNodeCnt<=3) { list.add(new int[] {nodeTotCnt,badNodeCnt}); } } }
标签:Code,恶意代码,感染,01,import,new,dp,设备 来源: https://www.cnblogs.com/smile_to_warm/p/15216139.html