HDU1213 How Many Tables【并查集】

How Many Tables

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 46003    Accepted Submission(s): 23043


 

Problem Description

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

Author

Ignatius.L

问题链接:HDU1213 How Many Tables

问题描述:今天是Ignatius的生日,他邀请了n个朋友,由于n个人中并不是每个人都互相认识,而且一个人不想和自己不认识的人在同一张桌子上吃饭,因此现在Ignatius需要统计需要多少张桌子,注意如果A和B虽不认识,但是A和B都认识C那么A和B也能在同一张桌子上吃饭,给出M对描述:A B表示A和B相互认识,问最少需要多少张桌子

解题思路:简单并查集,最后统计根的个数即可

AC的C++代码:

#include

using namespace std;

const int N=1005;
int pre[N];
void init(int n)
{
	for(int i=0;i<=n;i++)
	  pre[i]=i;
}

int find(int x)
{
	int r=x;
	while(r!=pre[r])
	  r=pre[r];
	//路径压缩
	while(x!=r){
		int i=pre[x];
		pre[x]=r;
		x=i;
	}
	return r; 
}

void join(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)
	  pre[fx]=fy;
}

int main()
{
	int t,n,m,a,b;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		init(n);
		while(m--){
			scanf("%d%d",&a,&b);
			join(a,b);
		}
		int ans=0;
		//统计根的个数 
		for(int i=1;i<=n;i++)
		  if(find(i)==i)
		    ans++;
		printf("%d\n",ans);
	}
	return 0;
}



 

你可能感兴趣的:(数据结构)