关闭

POJ2524_并查集

标签: ACM水题并查集算法导论
660人阅读 评论(0) 收藏 举报
分类:
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 12171   Accepted: 5759

Description

There are so many different religions in the world today that it is difficult to keep track of them all. You are interested in finding out how many different religions students in your university believe in. 

You know that there are n students in your university (0 < n <= 50000). It is infeasible for you to ask every student their religious beliefs. Furthermore, many students are not comfortable expressing their beliefs. One way to avoid these problems is to ask m (0 <= m <= n(n-1)/2) pairs of students and ask them whether they believe in the same religion (e.g. they may know if they both attend the same church). From this data, you may not know what each person believes in, but you can get an idea of the upper bound of how many different religions can be possibly represented on campus. You may assume that each student subscribes to at most one religion.

Input

The input consists of a number of cases. Each case starts with a line specifying the integers n and m. The next m lines each consists of two integers i and j, specifying that students i and j believe in the same religion. The students are numbered 1 to n. The end of input is specified by a line in which n = m = 0.

Output

For each test case, print on a single line the case number (starting with 1) followed by the maximum number of different religions that the students in the university believe in.

Sample Input

10 9
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
10 4
2 3
4 5
4 8
5 8
0 0

Sample Output

Case 1: 1
Case 2: 7

Hint

Huge input, scanf is recommended.
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

#define MAXN 50000
class UFS{
public:
	UFS(){
		memset(p,0,sizeof(p));
		memset(rank,0,sizeof(rank));
	}
	void Make_Set(int x){
		p[x] = x;
		rank[x] = 0;
	}
	void Union(int x, int y){
		Link(Find_Set(x),Find_Set(y));
	}
	void Link(int x, int y){
		if(rank[x] > rank[y]){
			p[y] = x;
		}
		else{
			p[x] = y;
			if(rank[x] == rank[y])
				rank[y]++;
		}
	}
	int Find_Set(int x){
		if(p[x]!=x)
			p[x] = Find_Set(p[x]);
		return p[x];
	}
private:
	int p[MAXN+4];
	int rank[MAXN+4];
};

//#define UNSUBMTI
int main()
{
#ifdef UNSUBMTI
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
#endif
	int m,n;
	int j,k;
	int t = 0;					//测试数据的组数
	int count;					//the number of religion
	UFS * religion = new UFS();
	while(scanf("%d%d",&n,&m)==2 && (n||m)!=0)
	{
		count = n;
		++t;
		for(int i=1; i<=n; i++)
			religion->Make_Set(i);
		for(int i=1; i<=m; i++){
			scanf("%d%d",&j,&k);
			religion->Union(j,k);
		}
		for(int i=1; i<=n; i++){
			if(religion->Find_Set(i)!=i)
				count--;
		}
		printf("Case %d: %d\n",t,count);
	}
	return 0;
}


1
0
查看评论

poj2524_并查集基础

和上一篇hdu1232基本一样,就cnt=-1改为cnt=0 #include int set[50005]; int find(int x) { int r=x; while(r!=set[r]){ r=set[r]; } int i=x; ...
  • u013700636
  • u013700636
  • 2014-03-12 01:09
  • 446

使用STL实现并查集

我以最入门的并查集水题——宗教信仰为例,来演示使用STL里的multimap(多重映照容器)模拟并查集数据结构(并查集应该也可以用其他STL实现,这里我仅以multimap为例)。 Multimap和map类似,不过可以插入重复键值,都要包含头文件,因为multimap可以插入重复键值,所以其搜索...
  • lhrsdl
  • lhrsdl
  • 2014-07-25 15:43
  • 1680

并查集 -- 学习详解

作者:Yx.Ac 出处:勇幸|Thinking (http://www.ahathinking.com)         昨天和今天学习了并查集和trie树,并练习了三道入门题目,理解更为深刻,觉得有必要总结一下,...
  • JDPlus
  • JDPlus
  • 2014-02-19 16:50
  • 3867

【并查集专题】【HDU】

How Many Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 14542...
  • zy691357966
  • zy691357966
  • 2014-11-29 18:34
  • 2261

带权值的并查集

题目链接:【POJ 1182】 好题! 父节点跟子节点之间一共有三种关系,父节点吃子节点,子节点吃父节点,父节点跟子节点是同类,所以用三进制表示 fa[B]=A,rank[B]=0表示与父节点是同类,rank[B]=1表示被父节点吃,rank[B]=2表示吃父节点 一共分两大类进行操作:1、x跟y的...
  • YHYYXT
  • YHYYXT
  • 2016-03-08 21:04
  • 943

图—并查集(解决朋友圈问题)

图也是一种 非线性结构,是由多个顶点组成的关系集合组成的一种数据结构。图可以分为两种,无向图和有向图。★图的定义:650) this.width=650;" width="525" height="243" title="无标题.png&q...
  • ttyue_123
  • ttyue_123
  • 2016-08-09 21:44
  • 622

关于可持久化并查集的学习和思考

鉴于noip比赛前集训时SAKER前辈教了我这个蒟蒻可持久化线段树以来,我懂得了如何维护一个支持历史查询的线段树。于是我就开始异想天开了:可不可以快速维护一个支持历史查询的数组呢? 就在这时,我上网看到了一个新的算法:可持久化并查集。先用例题来讲吧: BZOJ3674:可持久化并查集加强版 Desc...
  • KsCla
  • KsCla
  • 2016-12-12 19:55
  • 2640

并查集详解 ——图文解说,简单易懂(转)

并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了。以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定。不分享出来真是对不起party了。(party:我靠,关我嘛事啊?我跟你很熟么?) 来看一个实例,HDU1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后...
  • liujian20150808
  • liujian20150808
  • 2016-03-10 17:38
  • 2453

4并查集的合并与删除

Recognizing junk mails is a tough task. The method used here consists of two steps:1) Extract the common characteristics from the incoming email.2) Us...
  • mRango
  • mRango
  • 2016-07-06 22:53
  • 750

并查集的分析及应用

并查集的分析及简单应用,个人理解并作记录之用。 ————凌风 CSDN
  • IAccepted
  • IAccepted
  • 2014-01-27 21:34
  • 3308
    个人资料
    • 访问:968083次
    • 积分:13993
    • 等级:
    • 排名:第1070名
    • 原创:353篇
    • 转载:343篇
    • 译文:0篇
    • 评论:47条
    文章分类