数据结构与算法实验题 11.2 病毒排查问题 ★ 问题描述 : 最近,网络中心发现了一种传播能力很强的病毒。如果一台计算机感染了 这 种病毒,那么它可以通过网络传播到其它与其相联的计算机中。 现在,网络中心为了阻止这种病毒的传播,打算找出所有可能感染此病毒 的 计算机,并对这些计算机进行处理。我们假设如果一个网络中有一台计算机感 染 了此病毒,那么该网络中的其它计算机都有可能感染此病毒。现在给你各个网 络 的信息,要你找出有可能感染此病毒的计算机总数。 ★ 实验任务: 为了简化问题,我们假设学校有 N 台计算机,编号为 0 到 N - 1 , 0 号已确 定 感染了此病毒。接下给出每个网络中的计算机信息。注意,一台计算机可能同 时 加入好几个网络。现在要求你求出可能感染此病毒的计算机数目(包含已感染 的 0 号计算机)。 ★ 数据输入: 由文件 input.txt 给出输 入。 第一 行包 含两 个数 N(0<N<=30000) 与 M(0<=M<=500) ,表示有 N 台计算机, M 个网络。接下来 M 行,每行包含一个 网络信息。每行的第一个整数 K 表示这个网络中有 K 台计算机,接下来 K 个 数 Ki(1<=i<=k) 表示该网络中的计算机编号 (1<=K<=N,0<=Ki<N) 。 ★ 结果输出 : 一个整数 X ,表示可能感染病毒的计算机的总数。输出到 output.txt 。 输入示例 输出示例 input.txt 100 4 2 1 2 5 10 13 11 12 14 2 0 1 2 99 2 output.txt 4 第一次做并查集的题目。。。。。 本题要注意的是需要记录每个集合的节点个数,需要另外开一个数组来存储。 #include <stdio.h> #define NUMOFPOINT 30000 int parent[NUMOFPOINT]; //初始化为下标 int deep[NUMOFPOINT]; //初始化为1 int NumOfPoint[NUMOFPOINT]; //记录各棵树的节点个数,初始化为1 int Find(int n) { while (parent[n] != n) n = parent[n]; return n; } int Union(int a, int b) { int ParientA; int ParientB; ParientA = Find(a); ParientB = Find(b); if (ParientA == ParientB) return ParientA; if (deep[ParientA]>deep[ParientB]) { parent[ParientB] = ParientA; NumOfPoint[ParientA] += NumOfPoint[ParientB]; return ParientA; } else { parent[ParientA] = ParientB; NumOfPoint[ParientB] += NumOfPoint[ParientA]; if (deep[ParientA] == deep[ParientB]) deep[ParientB]++; return ParientB; } } void Init(int n) { int i; for (i=0;i<n;i++) { deep[i] = 1; parent[i] = i; NumOfPoint[i] = 1; } } int main() { int n,m,c,c1,i,k,j,un,un0; while (scanf("%d%d", &n, &m)!=EOF) { Init(n); for (i=0;i<m;i++) { scanf("%d", &k); scanf("%d", &c); un = c; for (j=0;j<k-1;j++) { scanf("%d", &c1); un = Union(un, c1); } } un0 = Find(0); printf("%d/n", NumOfPoint[un0]); } return 0; }