並查集加記錄個數
阿新 • • 發佈:2018-12-12
poj1611
輸入n個學生
m個集合,每個集合前有一個數為k,為集合元素個數
每個集合的第一號為傳染源,和它在一個集合 中的都為感染者,輸出感染人數
#include<stdio.h> #define MAX 30005 int a[MAX],pre[MAX]; int find(int x) { if(x!=pre[x]) //找到其祖先節點 pre[x] = find(pre[x]); //由父節點繼續向上遞迴查詢 ,並將其父節點變成找到的 return pre[x]; } void merge(int x,int y) { //分別查詢兩點的祖先節點。 int prex = find(x); int prey = find(y); //如果二者的祖先節點不一致,那麼任意讓二者中某一個認另一個為祖先,保證同集合。 if(prex == prey) { return ; } //應該是祖先節點進行組合。而不是當前節點! pre[prey] = prex; a[prex] += a[prey];//順序是因為0號是預設每行的根節點; } int main() { int n,m; int k,x,y; while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0) { return 0; } for(int i=0;i<n;i++) { //先將自身作為祖先節點。 pre[i] = i; a[i] = 1;//長度預設為1 } for(int i=0;i<m;i++) { //給出集合每個集合人數,以及第一個人的編號 scanf("%d%d",&k,&x);//x是每個集合中的傳染源; k--; while(k--) { scanf("%d",&y); merge(x,y);//每一行的x即第一個就是傳染源即根節點; } } printf("%d\n",a[find(0)]);//是a[find(0)]因為每一行根節點不定,a[0]可能還有根節點;這是為了找出它的最根節點 } return 0; }