图-并查集

package Week1;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

/*严重急性呼吸系统综合症(SARS)是一种病因不明的非典型肺炎,在2003年3月中
旬被确认为全球威胁。为了尽量减少传染给他人,最好的策略是将嫌疑人与其他人分开。
在不传播疾病的大学(NSSU)中,有很多学生群体。同一组的学生经常相互交流,一个学生可以加入几个组。为了防止SARS的可能传播,NSYSU收集所有学生团体
的成员名单,并在其标准操作程序(SOP)中制定以下规则。
一旦组中的某个成员是嫌疑犯,组中的所有成员都是嫌疑犯。 
然而,他们发现,当一名学生被认定为嫌疑犯时,识别所有嫌疑犯并不容易。你的工作是编写一个程序,找出所有的嫌疑犯。 
输入
输入文件包含几个案例。每个测试用例从一行中的两个整数n和m开始,其中n是学生数,m是组数。您可以假设0<n<=30000和0<=m<=500。
每个学生都由一个介于0和n-1之间,并且最初学生0在所有情况下都被视为嫌疑犯。这一行后面是m个组的成员列表,每个组一行。
每一行以一个整数k开始,该整数本身表示组中的成员数。在成员数之后,有k个整数代表该组中的学生。一行中的所有整数至少用一个空格分隔。 
n=0和m=0表示输入结束,无需处理。
输出 
对于每个案例,在一行中输出嫌疑犯的数量。
*/
//100 4
//2 1 2
//5 10 13 11 12 14
//2 0 1
//2 99 2
//200 2
//1 5
//5 1 2 3 4 5
//1 0
//0 0
public class D_Suspects {
   static int N,M,K;
   static int father[] = null;
   static int count[] = null;
   public static void main(String[] args) throws Exception {
      System.setIn(new FileInputStream("Solution.txt"));
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      while(true) {
          StringTokenizer st = new StringTokenizer(br.readLine());
          N = Integer.parseInt(st.nextToken());
          M = Integer.parseInt(st.nextToken());
          if(N==0 && M==0) {
              break;
          }
          father = new int[N+1];
          count = new int[N+1];
          Arrays.fill(count, 1);
          for (int i = 0; i < N; i++) {
            father[i]=i;
          }
          for(int i=1;i<=M;i++) {
              st = new StringTokenizer(br.readLine()); 
              K = Integer.parseInt(st.nextToken());
              int a=0;
              for (int j = 1; j <= K; j++) {
                  if(j==1) {
                      a = Integer.parseInt(st.nextToken());
                  } else {
                      int b = Integer.parseInt(st.nextToken());
                      int x = find(a);
                      int y = find(b);
                      if (x != y) {
                          if (x == 0) {
                              father[y] = 0;
                              count[0] += count[y];
                          }else if (y == 0) {
                              father[x] = 0;
                              count[0] += count[x];
                          }else {
                              father[x] = y;
                              count[y] += count[x];
//                              union(a,b);
//                              if(a<b) {
//                                  count[x] += count[y];
//                              } else {
//                                  count[y] += count[x];
//                              }
                          }
                      }
                 }
              }
          }
          System.out.println(count[0]);
      
     
      }
   }
   
   public static void union(int a,int b) {
       int x = find(a);
       int y = find(b);
       if(x<y) {
           father[y]=x;
       }
       if(x>y) {
           father[x]=y;
       }
   }
   
   public static int find(int i) {
       if(i == father[i]) {
           return i;
       }
       return father[i]=find(father[i]);
   }
   
}

 

posted @ 2021-08-01 18:40  没带壳的蜗牛  阅读(41)  评论(0)    收藏  举报