HDU - 1213 How Many Tables [并查集]
Posted jiaqi666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 1213 How Many Tables [并查集]相关的知识,希望对你有一定的参考价值。
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.
InputThe 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.
OutputFor 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
题意:今天是Ignatius的生日,她邀请了一些朋友在她家吃晚饭,这些朋友只和自己认识的人坐在同一桌,比如A认识B,B认识C,那么A,B,C可以坐在一桌,现在问Ignatius的晚餐至少要准备几张桌子?
思路:用并查集求连通分量的个数
在使用并查集之前,我们先要了解并查集是个什么东西
顾名思义,并查集的核心是合并和查询;并查集类似我们数据结构中学过的树结构,在实际应用中更像是对森林的操作,每个集合代表了一棵树,查询指的是查询某个结点
属于哪颗树,然后根据题意确定树的合并条件,将一些树合并,得到想要的结果。
查询->find函数
find函数是用来做什么的呢?就拿这道题来说,它是用来查询某个人所属的朋友圈的,假如A认识B,B又认识C,find(C)就是找C在哪个朋友圈,我们把靠前的作为朋友圈的领头羊,也就是A,A就标志了一个朋友圈,所以find(C) = A;
合并
假如A认识B和C, A,B,C要坐在一桌,D认识E和F, D,E,F要坐在一桌这时再来一个条件:A认识D,那这两桌人就可以坐在一起了,这时只要把这两个领头羊连接在一起就完成了合并操作。
了解了并查集的作用,这道题也就迎刃而解啦~
AC代码:
还有一些细节在代码注释里
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1050; int fa[maxn]; //朋友圈的领头羊们 int T, N, M; int u, v; //u和v认识 int Find(int u) //找u所在朋友圈的领头羊 { if(u == fa[u]) return fa[u]; else return fa[u] = Find(fa[u]); } void adde(int u, int v) //u和v是朋友 { int x = Find(u); //找x所在朋友圈的领头羊 int y = Find(v); //找y所在朋友圈的领头羊 if(x != y) fa[x] = fa[y]; //假如目前x和y所在朋友圈还不一样,那就把两个领头羊合为一体 } int main () { scanf("%d", &T); while(T--) { scanf("%d%d", &N, &M); for(int i = 1; i <= N; i++) fa[i] = i; //刚开始每个人自己是一个小团体 for(int i = 1; i <= M; i++) { scanf("%d%d", &u, &v); adde(u, v); //u和v所在朋友圈合并 } int ans = 0; //领头羊的个数,也就是桌子数 for(int i = 1; i <= N; i++) { if(fa[i] == i) ans++; } printf("%d\n", ans); } return 0; }
以上是关于HDU - 1213 How Many Tables [并查集]的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1213 How Many Tables(模板——并查集)
HDU - 1213 How Many Tables(并查集)