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

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
",ans-1);
    }
  return 0;
}
View Code
原文地址:https://www.cnblogs.com/zero-begin/p/4345474.html