HDU1213テーブル数(チェックセットも含む)

タイトルリンク:http : //acm.hdu.edu.cn/showproblem.php?pid=1213


 

問題の説明

今日はイグナチオの誕生日です。彼は多くの友人を招待した。今は夕食の時間です。Ignatiusは、少なくともいくつのテーブルが必要かを知りたいと思っています。すべての友達がお互いを知っているわけではなく、すべての友達が見知らぬ人と一緒にいたくないことに注意する必要があります。
この問題を解決するための重要なルールは、AがBを知っていて、BがCを知っていると言ったら、A、B、Cはお互いを知っているので、テーブルに留まることができます。
たとえば、AがBを知っており、BがCを知っており、DがEを知っている場合、A、B、Cは1つのテーブルにとどまることができ、D、Eは別のテーブルにとどまる必要があります。したがって、Ignatiusには少なくとも2つのテーブルが必要です。


 

入力値

入力は、テストケースの数を表す整数T(1 <= T <= 25)で始まります。次に、Tテストケースがあります。各テストケースは、2つの整数NおよびM(1 <= N、M <= 1000)で始まります。Nは友達の数を表し、友達には1からNまでのマークが付けられます。次に、ラインMに従います。各行には2つの整数AとB(A!= B)が含まれています。つまり、友達Aと友達Bはお互いを知っています。2つのケースの間に空白行があります。


 

 アウトプット

各テストケースについて、少なくともIgnatiusが必要とするテーブルの数を出力します。ブランクは印刷しないでください。


 

入力例

2

5 3

1 2

2 3

4 5


 

5 1

2 5


 

出力例

2

4


 

そして、操作手順を確認してください:

(1)初期化、配列int a []を定義し、ノードiを要素とするセットを確認します。最初に処理は行われません。各ポイントは分離されたセットです。要素iの値はそのセットa [i]を表します。たとえば、要素a [1] = 1;

(2)マージ、この質問の例(1、2)、(2、3)、(4、5)などの関連するものをマージします。ブロガーは、1,2,3は関連していると考えているため、最初に1を2に入れ、次に2を3に入れます。この場合、1、2、3は3のセットに属し、検索ツリーを構成します。 。

(3)検索、検索は再帰的なプロセスであり、そのセットに等しい要素が見つかるまで、この時点でルートノードのセットが見つかります

(4)セットの数を数える


 

 


 

 


 

 


 

 


1  / * 
2  * @説明: 
 3  * @バージョン: 
 4  * @作成者:ZKYAAA
 5  * @日付:2020-04-17 14:04:47
 6  * @LastEditors:请叫我ZK谕啊啊啊
 7  * @ LastEditTime:2020-04-17 19:41:16
 8   * / 
9  
10 #include <bits / stdc ++。h>
 11  名前空間std を使用 ;
12 #define _for(i、a、b)for(int i =(a); i <=(b); i ++)
 13 const int MAXN = 1050 ;
14 int a [MAXN];
15 int height [MAXN];
16 整数      i;
 17  
18  void init_set(){                 // 初期化
19 _for      (i、1 、MAXN){
 20          a [i] = i;
 21          height [i] = 0 ;             // 検索ツリーの高さ
22      }
 23  }
 24  
25  / * 
26  int find_set(int n){//再帰的な実装を検索
 27      if(n!= A [n])
 28          a [n] = find_set(a [n]); //パス圧縮
 29      return a [n] ;
 30  }
 31  * / 
32  
33  int find_set(int n){             // 非再帰的な実装を見つける
34      int r = n;
 35      while(a [r]!= r)r = a [r];       // ルートノードを見つける
36      int i = n、temp;
 37      while( i!= r){
 38          temp = a [i];               // ゼロ時間変数tempを使用して
39          a [i] = r;                  // ルートノードへのパス上の要素のセットを変更する
40          i = temp;
 41      }
 42      return r;
 43  }
 44  
45  void union_set(int x、int y){     // マージ
46      x = find_set(x);
 47      y = find_set(y);
 48      if(height [x] == height [y]){
 49          height [x] = height [x] + 1 ;   // マージ、ツリーの高さを
50          a 増加 [y] = x;
 51      }
 52      else {
 53          if(height [x] <height [y])// ドワーフツリーをトールツリー、ツリーの高さにマージ同じに保つ
54              a [x] = y;
 55          そうでなければ
56              a [y] = x;
 57      }
 58 }
 59  
60  int main(){
 61      int t、n、m、x、y;
62      cin >> t;
63      while(t-- ){
 64          cin >> n >> m;
65          init_set();
66          _for(i、1 、m){
 67              cin >> x >> y;
68              union_set(x、y);
69          }
 70          int sum = 0 ;
71          _for(i、1 、n){
 72              if(a [i] == i)
 73                 sum ++ ;
74          }
 75           cout << sum << endl;
76      }
 77は     0を返し ます78 }

 

おすすめ

転載: www.cnblogs.com/ZKYAAA/p/12722225.html