有空一起吃饭(并查集)

Description

小李今天请客吃饭,小李把认识的人都请了。准备定桌子的时候,小李突然想起来,他的某些朋友是互相连面都没见过的,为了照顾这些朋友不让他们和陌生人同桌,小李决定多订几张桌子,只让互相认识的人坐一桌。但是小李的朋友们很体谅他,说如果他们之间有共同的朋友,那他们也能勉强坐在一桌。
例如:
1.如果A认识B, B认识C,那A, B, C就可以坐一桌
2.但是如果A认识B, B认识C, D认识E,那么A、B、C可以坐在一起,而D和E就得坐另一张桌子一起吃饭

请你帮小李算算他最少要定多少张桌子才合适。

Input

第一行输入一个整数T(1<=T<=25),表示测试用例的数量
接下来是两个整数N和M(1<=N,M<=1000),N表示朋友的数量,朋友从1标记到N
之后的M行,每一行由两个整数A和B(A!=B)组成,这意味着朋友A和朋友B互相认识
每两组数据之间换行隔开

Output

对于每个测试用例,输出至少需要多少张桌子,不要打印多余的空格

Sample Input Copy

2
5 3
1 2
2 3
4 5

5 1
2 5

Sample Output Copy

2
4

#include<bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(false); cin.tie(NULL);
const int N = 1010;

int t,n,m,a,b;
int pre[N];
int find_pre(int x)//路径压缩找父节点
{
    if(x!=pre[x])
        pre[x]=find_pre(pre[x]);
    else
        return pre[x];
    return pre[x];
}

void join(int x,int y)
{
    int a = find_pre(x);
    int b = find_pre(y);
    if(a!=b)
    {
        pre[a]=b;
    }
}



int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(int i=1; i<=n; i++)//初始化
        {
            pre[i]=i;
        }
        while(m--)
        {
            cin>>a>>b;
            join(a,b);
        }
        int vis[N]= {0}; //标记出现过的父节点
        int cnt;
        int ans=0;
        for(int i=1; i<=n; i++)
        {
            cnt = find_pre(i);
            if(vis[cnt]==0)
            {
                ans++;
                vis[cnt]=1;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值