https://codeforces.com/contest/1167/problem/C
問題の意味:N Mの基であり、ユーザーは、各ユーザーが複数のパケットに表示されることが、パケットはまた、nullが可能となります。同じグループ内の全員に各ユーザーのCANメッセージ、個体数にメッセージを送信するために、各ユーザーにまで追求。
アイデア:互いに素セットを加重は、任意の一人の木は、木の上の皆にメッセージを渡すことができます。ポイントを維持するRKアレイは、ツリー(ルートを含む)ノードの数を有する属します。各ノードのRK出力値が答えであります
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 typedefの長い 長いLL。 const int型 MAXN = 5E5 + 5 。 int型PA [MAXN]。 INT RK [MAXN]。 INT(見つけるINT X){ 戻り PA [X] == Xか?X:PA [X] = (PAは、[X])を見つけます。 } ボイド(団結INT A、INT B){ A =検索(A)、B = (B)を見つけます。 もし(== b)は戻り、 もし(RK [A] < RK [B]){ PA [A] = B。 RK [B] + = RK [A]。 } 他{ PAは、[B] = 。 RK [A] + = RK [B]。 } } int型のmain(){ // freopenは( "datain.txt"、 "R"、STDIN)。 イオス:: sync_with_stdio(0 ); cin.tie(0 )。 INTのN、M。 CIN >> N >> M。 以下のために(int型 i = 0 ; iがn <; iは++)PAを[I] = I、RK [I] = 1 。 以下のために(int型 i = 0 ; iがm <; iは++ ){ int型のk; cinを>> K; もし(Kの== 0)続けます。 int型最後= - 1 、CUR。 cinを >> 最後。最終; 用(INT J = 1 ; J <K、J ++ ){ CIN >> CUR。CUR; (CUR、最後の)団結。 } } のために(int型 i = 1 ; iがn = <; iは++ ){ COUT << RK [見つける(I)] << ' ' 。 } // COUT << RK [見つける(0)]。 coutの<< てendl; }