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

个人分析:
这个题巧妙运用了并查集,也是我初识并查集,这个题就是一个并查集的模板!

关键代码分析:
为了解释并查集的原理,我将举一个更有爱的例子。 话说江湖上散落着各式各样的大侠,有上千个之多。他们没有什么正当职业,整天背着剑在外面走来走去,碰到和自己不是一路人的,就免不了要打一架。但大侠们有一个优点就是讲义气,绝对不打自己的朋友。而且他们信奉“朋友的朋友就是我的朋友”,只要是能通过朋友关系串联起来的,不管拐了多少个弯,都认为是自己人。这样一来,江湖上就形成了一个一个的群落,通过两两之间的朋友关系串联起来。而不在同一个群落的人,无论如何都无法通过朋友关系连起来,于是就可以放心往死了打。但是两个原本互不相识的人,如何判断是否属于一个朋友圈呢?
我们可以在每个朋友圈内推举出一个比较有名望的人,作为该圈子的代表人物,这样,每个圈子就可以这样命名“齐达内朋友之队”“罗纳尔多朋友之队”……两人只要互相对一下自己的队长是不是同一个人,就可以确定敌友关系了。
但是还有问题啊,大侠们只知道自己直接的朋友是谁,很多人压根就不认识队长,要判断自己的队长是谁,只能漫无目的的通过朋友的朋友关系问下去:“你是不是队长?你是不是队长?”这样一来,队长面子上挂不住了,而且效率太低,还有可能陷入无限循环中。于是队长下令,重新组队。队内所有人实行分等级制度,形成树状结构,我队长就是根节点,下面分别是二级队员、三级队员。每个人只要记住自己的上级是谁就行了。遇到判断敌友的时候,只要一层层向上问,直到最高层,就可以在短时间内确定队长是谁了。由于我们关心的只是两个人之间是否连通,至于他们是如何连通的,以及每个圈子内部的结构是怎样的,甚至队长是谁,并不重要。所以我们可以放任队长随意重新组队,只要不搞错敌友关系就好了。于是,门派产生了。


下面我们来看并查集的实现。 int pre[1000]; 这个数组,记录了每个大侠的上级是谁。大侠们从1或者0开始编号(依据题意而定),pre[15]=3就表示15号大侠的上级是3号大侠。如果一个人的上级就是他自己,那说明他就是掌门人了,查找到此为止。也有孤家寡人自成一派的,比如欧阳锋,那么他的上级就是他自己。每个人都只认自己的上级。比如胡青牛同学只知道自己的上级是杨左使。张无忌是谁?不认识!要想知道自己的掌门是谁,只能一级级查上去。
下面就是找自己的掌门的函数find_pre()
如果找到了就返回掌门号,不然就一直递归下去,一级级查上去!

int find_pre(int x)
{if(x==pre[x]){return x;}else{return find_pre(pre[x]);}
}

再来看看join函数,就是在两个点之间连一条线,这样一来,原先它们所在的两个板块的所有点就都可以互通了。这在图上很好办,画条线就行了。但我们现在是用并查集来描述武林中的状况的,一共只有一个pre[]数组,该如何实现呢? 还是举江湖的例子,假设现在武林中的形势如图所示。虚竹小和尚与周芷若MM是我非常喜欢的两个人物,他们的终极boss分别是玄慈方丈和灭绝师太,那明显就是两个阵营了。我不希望他们互相打架,就对他俩说:“你们两位拉拉勾,做好朋友吧。”他们看在我的面子上,同意了。这一同意可非同小可,整个少林和峨眉派的人就不能打架了。这么重大的变化,可如何实现呀,要改动多少地方?其实非常简单,我对玄慈方丈说:“大师,麻烦你把你的上级改为灭绝师太吧。这样一来,两派原先的所有人员的终极boss都是师太,那还打个球啊!反正我们关心的只是连通性,门派内部的结构不要紧的。”玄慈一听肯定火大了:“我靠,凭什么是我变成她手下呀,怎么不反过来?我抗议!”抗议无效,上天安排的,最大。反正谁加入谁效果是一样的,我就随手指定了一个。这段函数的意思很明白了吧?
下面的是join函数,就相当于连接门派,这里pre[ b ] = a 写成pre[ a ] = b 也是对的,只要随手指定就可以了~

void join(int x,int y)
{int a=find_pre(x);int b=find_pre(y);if(a!=b){pre[b]=a;}
}

做题感受:
刚开始还打算用set+map来做的,因为上一个博客也是类似的如果A认识B B认识C 那么A就认识C 然后确定个数 显然不对,后面查看了一下题解,居然用并查集,可是我不会~ 不会就得学啊! 下面部分故事是转载的,别人写的很优秀,然后我就痴迷了倚天屠龙记了~~~

另外,对于最后结果的输出,需要多少张桌子,我习惯上用res来代表结果变量,首先初始化为0,然后进行判断:如果此时的 i 就是掌门,那么res就++ 代表一个小集合,就拿样例1来说,123一张桌子 4 5 一张桌子,那么结果就是两张桌子咯,也就相当于两个小集合!

具体代码如下:
AC

#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<map>
#include<bits/stdc++.h>
#include<stack>
#include<functional>
#include<cstring>
#include<set>
#include<strstream>
#include<vector>
using namespace std;
const int maxn=1000+8;
int pre[maxn];
int find_pre(int x)
{if(x==pre[x]){return x;}else{return find_pre(pre[x]);}
}void join(int x,int y)
{int a=find_pre(x);int b=find_pre(y);if(a!=b){pre[b]=a;}
}int main()
{int t;cin>>t;while(t--){int n,m;cin>>n>>m;for(int i=1;i<=n;i++){pre[i]=i;}for(int i=0;i<m;i++){int x,y;cin>>x>>y;join(x,y);}int res=0;for(int i=1;i<=n;i++){if(pre[i]==i){++res;}}cout<<res<<endl;}return 0;
}
学如逆水行舟,不进则退

ACM2019春季训练- How Many Tables HDU - 1213(初识并查集+转倚天屠龙记故事)相关推荐

  1. 27行代码AC_How Many Tables HDU - 1213(并查集讲解)

    励志用少的代码做高效表达 分析与思路 n个人吃饭,只能熟人和熟人坐在一起,否则就一个人坐一桌. 给定m个关系(m对熟人),问最少需要多少张桌子. 纯粹考查的并查集模板的题, 给定m个关系就代表了m个集 ...

  2. hdu 1213 HowManyTables 并查集

    题意: 这个问题的一个重要规则是,如果A知道B,B知道C,这意味着A,B,C互相了解,所以他们可以呆在一张桌子上. 例如:如果我告诉你A知道B,B知道C,D知道E,那么A,B,C可以留在一张桌子上,D ...

  3. hdu 1232 经典并查集应用

    http://acm.hdu.edu.cn/showproblem.php?pid=1232 完全就是并查集的应用啊... View Code 1 #include<iostream> 2 ...

  4. 畅通工程 hdu 1232 HDU - 1863 (并查集+最小生成树)

    畅通工程hdu 1232 并查集 Problem Description Input Output 参考代码 HDU - 1863 Problem Description Input Output 参 ...

  5. HDU 3234 Exclusive-OR [并查集]

    http://acm.hdu.edu.cn/showproblem.php?pid=3234 #Description 给你N个数,X0-X(N-1) 执行Q个查询 三种格式 I p v Xp= v ...

  6. HDU 3234 Exclusive-OR(并查集)

    转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:给出N个数,给出一些条件, ...

  7. (并查集)How Many Tables -- HDU --1213

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1213 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  8. hdu 1325poj 1308 并查集(未解决)(掌握率50%)

    http://acm.hdu.edu.cn/showproblem.php?pid=1325 留个坑,超级大坑题 转载于:https://www.cnblogs.com/ccccnzb/p/38356 ...

  9. hdu 4496 D-City 并查集

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4496 题意: 给你个图,他不断删边,然后问你联通块的个数 题解: 我们可以逆向认为所有的点全是独立的 ...

最新文章

  1. 关于程序多开的尝试。CreateMutex,OpenMuxtex,ReleaseMutex
  2. python3 获取file大小_Python 3.x 连接数据库(pymysql 方式),程序员必备知识点
  3. 随机给出三十道四则运算题目
  4. java写一个类吧,能不能自己写个java自带的类
  5. Linux下使用fstatfs/statfs查询系统相关信息
  6. Flutter 萌新高频问题(加班猿妈妈叫你回家吃饭了)
  7. shell逻辑判断和-a区别
  8. 兵器簿之Alcatraz(插件管理神器)的配置和使用
  9. 小Z的袜子(bzoj 2038)
  10. wpd小波包分解_基于奇异值分解和小波包分解的故障检测
  11. When Does Self-Supervision Help Graph Convolutional Networks?
  12. 诗词对仗常用字表(笠翁对韵)
  13. kali linux国内源
  14. linux解压zip、tar压缩包
  15. 相对熵(KL散度)计算过程
  16. 18年大专毕业,转行入职车载测试岗位,薪资13K
  17. After Effects Guru: Advanced Photoshop Integration After Effects 大师教程之与Photoshop集成高级技巧 Lynda课程中文字幕
  18. 小猫爪:S32K3学习笔记04-S32K3之LCU
  19. 岭南(含广东广西海南)地形及DEM下载
  20. 网络文件共享服务(三):NFS

热门文章

  1. 图像傅里叶变换的幅度谱和相位谱的以及反变换
  2. 还在疑惑并发和并行?
  3. 超级硬核!Java 自学路线总结,已 Get 大厂 Offer,建议立马收藏!
  4. 人工神经网络算法与机器算法是相同的算法吗
  5. 量化交易是不是用机器预测股票涨跌?这靠谱吗?
  6. MySQL在linux上(cmake)的source code安装方法
  7. 日活4亿的抖音,为何没能孵化出第二个拼多多?
  8. mysql字段值是什么_什么是数据库字段值
  9. Transition Docbook
  10. 深度学习模型的构建三、优化函数optimizer