广工校赛——并查集——变形金刚

Description

有一天Stubird买了一台变形金刚,店员说,这台变形金刚和其他那种骗小孩子的不一样 他真的能变形。 这台变形金刚有n个部件,他们能互相连接,组成机器人,当然,也可以变形。 但是有一天,The tesseract 的能量突然消失了,部件散落一地,当然有些部件还连接着。 现在你只有把部件全部连接起来,他就能变回原样,例如,有4个部件,1,2是连接的,3,4也是连接着的 ,你只需要把1和3连接起来(1,4或者2,3或者2,4)他就能变回原样啦。 他现在问你最少需要多少次连接才能把它变回原样?

Input

第一行一个T,表示有T个测试样例 接下来一个n和m(n<=10^5,0<=m<=10^5),n表示部件个数,m表示有多少个部件还连接着 下面m行,每行u,v表示部件u,v是连接着的。(1<=u,v<=n)

Output

求最小的连接次数

Sample Input

2 1 0 5 2 1 2 3 4

Sample Output

0 2

HINT

大意:简单并查集~~~

主要并查集就三部,建立find函数,建立join函数,p[i]的赋值

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

const int MAX = 100100;

int p[MAX],t[MAX];

int find(int x){

  return x == p[x] ? x:p[x] = find(p[x]);

}

void join(int x,int y){

    int fx = find(x);

    int fy = find(y);

    if(fx!=fy)

    p[fx] = fy;

}

int main()

{

    int T,n,x,y,m;

    scanf("%d",&T);

    while(T--){

            memset(t,0,sizeof(t));

            scanf("%d%d",&n,&m);

            for(int i = 1; i <= n ; i++)

                p[i] = i;

         for(int i = 1; i <= m ; i++){

          scanf("%d%d",&x,&y);

          join(x,y);

         }

         for(int i = 1; i <= n ; i++)

            t[find(i)] = 1;

          int ans = 0;

          for(int i = 1; i <= n ; i++)

            if(t[i])

            ans++;

         printf("%d\n",ans-1);

    }

  return 0;

}
View Code

 

你可能感兴趣的:(并查集)