HDU 1213 How Many Tables (并查集,常规)
2015-06-29 16:39
246 查看
并查集基本知识看:http://blog.csdn.net/dellaserss/article/details/7724401
题意:假设一张桌子可坐无限多人,小明准备邀请一些朋友来,所有有关系的朋友都可以坐同一张桌,没有关系的则要另开一桌,问需要多少张桌子(小明不坐,不考虑小明与其他人的关系)?
思路:常规的并查集。要求出所有人的老大,有几个老大就要几张桌子。那么有关系的都归为同一个老大。用数组实现,再顺便压缩路径。
AC代码
题意:假设一张桌子可坐无限多人,小明准备邀请一些朋友来,所有有关系的朋友都可以坐同一张桌,没有关系的则要另开一桌,问需要多少张桌子(小明不坐,不考虑小明与其他人的关系)?
思路:常规的并查集。要求出所有人的老大,有几个老大就要几张桌子。那么有关系的都归为同一个老大。用数组实现,再顺便压缩路径。
#include <bits/stdc++.h> #define LL long long using namespace std; const int N=1005; int pre ; //结点i的上级 inline void init(int n){for(int i=1; i<=n; i++) pre[i]=i;} //将上级初始化为自己 int find(int x) //找x的上级 { int k=x; while(pre[x]!=x) x=pre[x]; //找上级 int tmp; while(pre[k]!=x) //优化:路径压缩 { tmp=pre[k]; pre[k]=x; k=tmp; } return x; } void joint(int a,int b) //将a和b合并为一个集合 { a=find(a); b=find(b); if(a!=b) pre[a]=b; } int check(int n) //查查到底需要几张桌子 { set<int> sett; for(int i=1; i<=n; i++) find(i); //防漏网之鱼,将所有人的老大推到最顶。 for(int i=1; i<=n; i++) sett.insert(pre[i]); return sett.size(); } int main() { //freopen("e://input.txt", "r", stdin); int t, n, m, a, b; cin>>t; while(t--) { scanf("%d%d", &n, &m); init(n); for(int i=0; i<m; i++) { scanf("%d%d",&a,&b); joint(a,b); } printf("%d\n",check(n)); } return 0; }
AC代码
相关文章推荐
- OAuth 2.0系列教程(一)引言
- java基础学习之(二):Java中的关键字
- iOS开发之查找目录
- android 制作天气预报软件
- 初识贝叶斯网络
- Spring MVC 读取静态资源时404错误
- HTML DOM节点的增删改查
- 各种github头像,找一个适合你的!
- String 常用方法最优算法实现总结 (三) -- findCommonSubstring 和difference
- java中static{}语句块详解
- ***php 数组添加关联元素的方法小结(关联数组添加元素)
- 关于beta分布 狄利克雷分布 共轭先验
- 黑马程序员——Java基础---String类和基本数据类型包装类
- 爬虫名称
- Harry Potter and the Goblet of Fire
- IOS根据两个经纬度计算相距距离
- Android常见问题及开发经验总结(二)
- modprobe、insmod内核模块区别
- [总结]视音频编解码技术零基础学习方法
- HttpWebRequest