模板
#include <iostream>
using namespace std;
const int MAX=1001;
int set[MAX];
void init(int N)
{
for(int i=1;i<=N;i++)
{
set[i]=i;//把每个元素的初始根设置为自己
//在本题中的意思是每个人最初单独一桌
}
}
int Find_set(int x)
{
return x==set[x]?x:set[x]=Find_set(set[x]);
//三目运算符
//(表达式)?结论一:结论二
// 满足表达式条件时该式的值为结论一不满足则为结论二
//判断x是否在最初的set[x]若在则直接返回
//若不在则再次调用该函数寻找其根set[x]的根set[set[x]]直到找到最根本的那个根
//并且在每次调用的时候直接将该set[x]等于Find_set(set[x])的值
//将每个找根过程中经过的点的根都赋值为最根本的那个根(递归路径压缩)
}
void Union(int x,int y)//合并
{
int tx=Find_set(x);
int ty=Find_set(y);
//调用该函数分别找到x和y的根
//根在此处具体指坐在自己最初桌子上的人
if(tx!=ty)
{
set[ty]=tx;//将ty所指并到tx中去
}
}
int main()
{
int T,N,M;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
init(N);
for(int i=0;i<M;i++)
{
int a,b;
scanf("%d%d",&a,&b);
//输入a和b是朋友
Union(a,b);
//把a和b所在的桌子并成一桌
}
int cnt=0;//计数器
//本题中为记录一共有多少桌
for(int i=1;i<=N;i++)
{
if(set[i]==i)
{
cnt++;//当该点位于自己原先所在的位置时被记录
//本题中为计算坐在自己最初的桌子上的人有多少也就表示有多少张桌子
}
}
printf("%d\n",cnt);
//输出有多少桌
}
return 0;
}
热闹的聚会
Problem Description
今天是小明的生日,他邀请了许多朋友参加聚会,当然,有些朋友之间由于互不认识,因此不愿意坐在同一张桌上,但是如果A认识B,且B认识C,那么A和C就算是认识的。
为了使得聚