1. 程式人生 > 其它 >圖-並查集

圖-並查集

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]); } }