容疑者
重症急性呼吸器症候群(SARS)、原因不明の非定型肺炎は、他者への送信を最小限に抑えるために半ば2003年3月に世界的な脅威として認識された、最善の戦略は、他の人から容疑者を分離することです。
拡散はない-あなたの酔い大学(NSYSU)では、多くの学生のグループがあります。頻繁にお互いに同じグループで相互の学生、そして学生は、いくつかのグループに参加することができます。SARSの可能性のある送信を防ぐために、NSYSUは、すべての学生グループのメンバーリストを収集し、その標準作業手順(SOP)に以下のルールを作ります。
グループのメンバーが容疑者になると、グループ内のすべてのメンバーは、容疑者です。
しかし、彼らは学生が容疑者として認識されている場合、それはすべての容疑者を特定することは容易ではないことがわかります。あなたの仕事は、すべての容疑者を発見するプログラムを書くことです。
拡散はない-あなたの酔い大学(NSYSU)では、多くの学生のグループがあります。頻繁にお互いに同じグループで相互の学生、そして学生は、いくつかのグループに参加することができます。SARSの可能性のある送信を防ぐために、NSYSUは、すべての学生グループのメンバーリストを収集し、その標準作業手順(SOP)に以下のルールを作ります。
グループのメンバーが容疑者になると、グループ内のすべてのメンバーは、容疑者です。
しかし、彼らは学生が容疑者として認識されている場合、それはすべての容疑者を特定することは容易ではないことがわかります。あなたの仕事は、すべての容疑者を発見するプログラムを書くことです。
入力
入力ファイルは、いくつかの例が含まれています。各テストケースは、nは、学生の数であり、mはグループの数であるライン内の2つの整数n及びmで始まります。あなたは0 <N <= 30000及び0 <= M <= 500すべての学生が0とn-1との間の一意の整数により番号付けされ、そして最初生徒0は、すべての場合において容疑者として認識されていることを仮定してもよいです。このラインは、グループのMメンバーリスト、グループごとに1つの行が続きます。各ラインは、グループ内のメンバーの数を表す単独で整数kから始まります。メンバーの数に続いて、このグループの学生を代表するk個の整数があります。行のすべての整数は、少なくとも1つのスペースで区切られます。
N = 0の場合であり、m = 0、入力の終了を示し、そして処理される必要はありません。
N = 0の場合であり、m = 0、入力の終了を示し、そして処理される必要はありません。
出力
各場合について、出力1つのラインの容疑者の数。
サンプル入力
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
サンプル出力
4 1 1
まず、アレイを定義:FA []は、この父のノードの点を表し、
互いに素セットは、3つの部分の合計が含まれています。
1:最初にすべての父ノードの初期化は、彼自身のポイントとして定義されています
1 空隙 INIT(INT N) 2 { 3の ための(INT iが= 0 ; <I = N; I ++ ) 4 FA [I] = I。 5 }
2:ルートノードのポイントを見つけるために父親が自分の場合は父親のノード父のノードを見つけることがない場合、彼は、父ノードであります
彼の父親は彼自身のノードになるまで
1件の int型の検索(int型V) 2 { 3 であれば(V == FA [V]) 4 戻りV。 5 FA [V] = (FA [V])を見つけます。 6 戻りFA [V]。 7 }
3.それらマージの2つに指している別のノードに親ノードの数をマージ
1 空隙更新(INT U、INT V) 2 { 3 int型 FU = (U)を見つけます。 4 INT FV = (V)を求めます。 5 FA [FU] = FV。 6 }
データの各セットの人々は(互いに素なセットテンプレートを参照)を組み合わせ、そして最終的にだけ一組と1から0までのすべてのNそのか否かを判断しています。即ちFA [I] = FA [0]
1の#include <cstdioを> 2の#include <iostreamの> 3の#include <アルゴリズム> 4の#include <CStringの> 5 使用して 名前空間をSTD。 6 INT N、M。 7 INT K、[ 30000 ]。 8 int型の FA [ 30000 ]。 9 ボイドのinit(int型N) 10 { 11 のために(INTは iは= 0 ; iが<= N; I ++ ) 12 のFA [I] = I。 13 } 14 INT(見つけるINT V) 15 { 16 場合(V == FA [V]) 17 リターンV。 18 FA [V] = (FAは[V])を見つけます。 19 リターンFA [V]。 20 } 21 空隙更新(INT U、INT V) 22 { 23 のint = FU (U)を見つけます。 図24は、 INT FV = (V)を求めます。 25 FA [FU] = FV。 26 } 27 のint main()の 28 { 29 ながら(scanf関数(" %D%D "、&N、&M)&& N + M =!0 ) 30 { 31 INT ANS = 0 。 32 のmemset( - 1、はsizeof ())。 33 INIT(N) 34 のために(INT iは= 1 ; iが<= M; I ++ ) 35 { 36 のscanf(" %dの"、&K)。 37 のための(int型 J = 1 ; J <= K J ++ ) 38 { 39 のscanf(" %dの"、&[J])。 40 であれば(J =!1 ) 41 更新([J]、[J- 1 ])。 42 } 43 } 44 のために(INT J = 0 ; J <= N; J ++ ) 45 { 46 であれば(見つける(J)(見つける== 0 )) 47の ANSを++ 。 48 } 49 COUT << ANS << ENDL。 50 } 51 リターン 0 。 52 }