HDU1213 How Many Tables

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

题目大致意思:有n个客人,有m组两个客人之间的关系,代表两个客人之间相互认识,然后要给客人们安排桌子,客人们与其他人坐同一张桌子的条件是这张桌子上至少有一个人是他认识的,问你最少要安排多少张桌子。比如第一组样例,1和2认识,2又和3认识,那么1,2,3就可以坐同一张桌子,而4,5和1,2,3互相不认识,所以他们不能坐同一张桌子,而4,5相互认识,所以4和5可以坐同一张桌子,所以总共需要两张桌子。

代码里面有比喻的注释,是我自己根据学习别人的并查集文章学来的。有关门派的

// How Many Tables.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

//#include "pch.h"
#include <iostream>
#include<algorithm>
using namespace std;
int up[1002];	//存放掌门人的数组
void ini(int n)	//初始化掌门人数组
{
	for (int i = 1; i <= n; i++)
		up[i] = i;		//每个人最开始,默认掌门人都是自己
}


int findd(int x)		//找自己的掌门人
{
	if (up[x] != x)		//如果自己不是教派的掌门人
		up[x] = findd(up[x]);	//向自己的上一级大哥找
	return up[x];	//当自己就是掌门人的时候,返回值告诉大家
}

void unionn(int a, int b)  //看看a,b两人是否是一个教派
{
	int x = findd(a);
	int y = findd(b);
	if (x != y)
		up[y] = x;		//不是一个教派,又同时进入这个函数
		//那化干戈为玉帛,a把b的所有小弟包括b收编,成为自己教派
}


int main()
{
	int cnt;
	int n, m;	//n是有n个人要分教派,m是有m层人物关系
	int a, b;	//a,b是两个人物
	cin >> cnt;
	while (cnt--)
	{
		int ans = 0;
		cin >> n >> m;
		ini(n);		//初始化每个人的教派,最开始都是自己管自己
		for (int i = 1; i <= m; i++)
		{
			cin >> a >> b;  //输入有交流关系的两个人
			unionn(a, b);	//a收编b
		}
		for (int i = 1; i <= n; i++)//查找这n个人里面,看谁是掌门
		{
			if (findd(i) == i)	//如果这个人,管他的人只有自己
								//那他就是掌门
				ans++;	//这样就多了一个门派
		}
		cout << ans << endl;	//输出总共有多少个门派
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值