您的位置:首页 > 其它

HDU-1213 How Many Tables

2018-04-03 21:57 288 查看
Today is Ignatius’ birthday. He invites a lot of friends. Now it’s dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want to stay with strangers.

One important rule for this problem is that if I tell you A knows B, and B knows C, that means A, B, C know each other, so they can stay in one table.

For example: If I tell you A knows B, B knows C, and D knows E, so A, B, C can stay in one table, and D, E have to stay in the other one. So Ignatius needs 2 tables at least.

Input

The input starts with an integer T(1<=T<=25) which indicate the number of test cases. Then T test cases follow. Each test case starts with two integers N and M(1<=N,M<=1000). N indicates the number of friends, the friends are marked from 1 to N. Then M lines follow. Each line consists of two integers A and B(A!=B), that means friend A and friend B know each other. There will be a blank line between two cases.

Output

For each test case, just output how many tables Ignatius needs at least. Do NOT print any blanks.

Sample Input

2

5 3

1 2

2 3

4 5

5 1

2 5

Sample Output

2

4

题目大意:某人生日派对,给定T组测试样例,N为参与派对朋友的数量,M为线索的数量,线索是指编号为A,B的两人互相认识。朋友的朋友也是朋友。互相认识的可以坐一桌,否则不可以。问需要准备几桌?

思路 :基础的并查集,由于这是我第一次解决并查集问题,所有来个奠基性质的博文。建立一个一维数组,数组下标代表编号,值代表该编号的“老大”,合并每一个人的老大看最后能组成多少个互不相干的朋友圈。这里说下并查集的原则,在啊哈算法中形容为“”靠左法则——指两个人如果互不相识则右边认左边为老大,和“擒贼先擒王法则”,——指每次让老大互相投靠即可,小BOSS的老大会在函数递归过程中被修改(路径压缩)。

代码如下:

#include<iostream>
#include<cstring>
using namespace std;
int father[1010]={0};
int getf(int m)
{
if(m==father[m])return m;//我就是老大
else return father[m]=getf(father[m]);//我不是老大,要找老大(路径压缩,将途中
//遇到的人的老大都改为最终老大,提高今后找老大的速度)
}
void merge(int a,int b)
{
int t1=getf(a);//找到a的老大
int t2=getf(b);//找到b的老大
if(t1!=t2)//老大不一样
{
//  father[b]=t1;//b投靠a的老大
father[t2]=t1;//b的老大也投靠a的老大
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)father[i]=i;//初始化,所有人互不相识
for(int i=0;i<m;i++)
{
int a,b;
cin>>a>>b;
merge(a,b);//合并朋友圈
}
int sum=0;
for(int i=1;i<=n;i++)if(father[i]==i)sum++;//统计有多少个独立的朋友圈
cout<<sum<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: