题意:
今天是伊格内修斯的生日。
他邀请了很多朋友。
现在是晚餐时间。
伊格内修斯想知道他至少需要多少张桌子。
你必须注意,并非所有的朋友都彼此认识,所有的朋友都不想和陌生人呆在一起。
这个问题的一个重要原则是,如果我告诉你A知道B,B知道C,那就意味着A,B,C彼此了解,所以他们可以呆在一张桌子里。
例如:如果我告诉你A知道B,B知道C,D知道E,那么A,B,C可以留在一张桌子上,而D,E必须留在另一张桌子上。 所以Ignatius至少需要2张牌桌。
这个问题的一个重要原则是,如果我告诉你A知道B,B知道C,那就意味着A,B,C彼此了解,所以他们可以呆在一张桌子里。
例如:如果我告诉你A知道B,B知道C,D知道E,那么A,B,C可以留在一张桌子上,而D,E必须留在另一张桌子上。 所以Ignatius至少需要2张牌桌。
解题思路:这是一个简单的并查集的应用,把每个人当作一个集合,两个人认识,就把两个集合并在一起,最后数有多少个集合。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1010;
int people[maxn];
void init(int n)//初始化
{
for(int i=1;i<=n;i++)
people[i]=i;
return;
}
int findset(int a)//查找
{
while(people[a]!=a)
{
a=people[a];
}
return a;
}
void union_nodes(int a,int b)//合并
{
int a1=findset(a);
int b1=findset(b);
if(a1!=b1)
{
people[a1]=b1;
}
return;
}
int main()
{
int t;
int n,m;
int a,b;
scanf("%d",&t);
for(int i=0;i<t;i++)
{
scanf("%d%d",&n,&m);
init(n);
int count=0;
for(int j=0;j<m;j++)
{
scanf("%d%d",&a,&b);
union_nodes(a,b);
}
for(int j=1;j<=n;j++)
{
if(people[j]==j)
count++;
}
printf("%d\n",count);
}
return 0;
}