其他分享
首页 > 其他分享> > 恶意代码 - Malicious Code - BFS & 01背包

恶意代码 - 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