HDU2473 - Junk-Mail Filter 利用虚拟数组实现删除并查集的节点

HDU2473 - Junk-Mail Filter: http://acm.hdu.edu.cn/showproblem.php?pid=2473

题目大意: M a b,代表a和b是同一类的,S a,代表原先给出的a的信息是错的,现在将其单独分成一类. 求最后一共有多少类邮件.

若只是分类,很直接就会想到并查集.但这里若直接用并查集是会出错的,因为删除的那个节点后面还可能会有其他的子节点,若直接把其删除,结果会出错. 这里就需要用到一个虚拟数组Trick,和Father数组合作,实现"删除"的目的(实际上该节点还是存在的).

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 1000111*2;
int N,M;
int x,y;
int cnt,Case = 0,Ans;
int Trick[MAXN],Father[MAXN],Hash[MAXN];
void Initial()
{
	cnt = N;
    Ans = 0;
	for(int i = 0;i < MAXN;i++)//另开一个虚拟数组Trick,开始和Father储存一样的信息
		Father[i] = Trick[i] = i,Hash[i] = 0;
}
int Find(int x)
{
	if(x == Father[x])return x;
	return Father[x] = Find(Father[x]);
}
void Union(int x,int y)
{
	x = Find(x);
	y = Find(y);
	if(x != y)
		Father[y] = x;
}
void Delete(int x)
{
	Father[cnt] = cnt;//传进来的是Trick的信息,这里改变并不会影响x的子节点的查询
	Trick[x] = cnt++;//更新后的信息在Trick里面,删除了x,表示x单独成为一个集合
}
char op[5];
int main()
{
	while(~scanf("%d%d",&N,&M),N + M)
	{
		Initial();
		while(M--)
		{
			scanf("%s",op);
			if(op[0] == 'M')
			{
				scanf("%d%d",&x,&y);
				Union(Trick[x],Trick[y]);//传进去的是Trick里的信息,但查找合并的时候用的是Father,信息还是储存在Trick里,没有被破坏
			}else{
				scanf("%d",&x);
				Delete(x);//删除x节点
			}
		}
		for(int i = 0;i < N;i++)//只有N个人是不会变的,查找一共被分成了几个集合
		{
			x = Find(Trick[i]);
			if(!Hash[x])Hash[x] = 1,Ans++;
		}
		printf("Case #%d: %d\n",++Case,Ans);
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-08 01:11:17

HDU2473 - Junk-Mail Filter 利用虚拟数组实现删除并查集的节点的相关文章

poj 3415 后缀数组分组+排序+并查集

Source Code Problem: 3415   User: wangyucheng Memory: 16492K   Time: 704MS Language: C++   Result: Accepted Source Code #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 510000

bzoj 4199: [Noi2015]品酒大会【后缀数组+单调栈+并查集】

用SA求出height数组,然后发现每个height值都有一个贡献区间(因为点对之间要依次取min) 用单调栈处理出区间,第一问就做完了 然后用并查集维护每个点的贡献(?),从大到小枚举height,因为这样区间是不断增大的所以并查集合并即可 #include<iostream> #include<cstdio> #include<vector> #include<algorithm> using namespace std; const int N=300

HDU 2473 Junk-Mail Filter (并查集的删除操作)

Problem Description 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) Use a filter matching the set of common characteristics extracted to determine w

hdu2473 Junk-Mail Filter(并查集(虚拟父亲)+删点)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2473 Problem Description Recognizing junk mails is a tough task. The method used here consists of two steps: 1) Extract the common characteristics from the incomin

利用虚拟索引(Virtual Index)优化数据库的案例分析

当我们在对生产库做优化的时候,主要就是对SQL语句的优化,包括语句的等价改写等,但其中很大一部分情况,又与索引有关.如果能合理利用合适的索引,可以使原本走全表扫描产生的逻辑读大大降低,提高数据库的性能.由于Oracle数据库中的索引本身就要占用磁盘空间,维护索引需要一定的开销,如何才能知道创建某个索引,会给数据带来性能的提升,而又不至于判断失误,创建了一个不恰当的索引,最后又不得不删除呢?这种情况下,我们可以利用Oralce提供的虚拟索引,即nosegment索引,它并不占用磁盘资源,只是在数据

Jquery利用JSON数组创建表格

$(function () { var json = [ { "name": "张三", "age": "20", "gender": "男" }, { "name": "李四", "age": "21", "gender": "女" }, { "name&q

利用后缀数组构造后缀树

由于蒟蒻azui前段时间忙着准备省选,并在省选中闷声滚大粗,博客停更了好久.. 省选过后整个人各种颓,整天玩玩泥巴什么的... 前段时间学后缀数组的时候上网查相关资料,看到说后缀数组和后缀树是可以相互转化的,并且uoj上有大量通过后缀自动机建出后缀树然后dfs遍历获得后缀数组的模板,但是通过后缀数组来建后缀树的资料确实稀缺. 也许大牛们都觉得这xjbYY一下就可以写了,所以网上没找到对应的代码,那么我来补个坑吧.大牛勿喷.. 先谈谈我的理解吧.. 讲道理后缀数组和后缀树应该是完全等价的,但前两者

利用虚拟光驱安装大型软件

利用虚拟光驱安装大型软件 这种方法适用于软件安装程序被打包成一个ISO镜像文件的情况,通常是ISO操作系统镜像.比如,你要安装一个ISO格式的软件,正常情况下,你先要解压,然后再点击安装程序进行安装.文件很大的时候,解压需要花费较长时间,而通过虚拟光驱加载的形式,就能大大减少安装时间,提高你的工作效率. 操作步骤: 1. 这里利用的是一款压缩软件的虚拟光驱功能,我用的是2345好压,当然你也可以用其它虚拟光驱工具. 2. 选中ISO镜像安装包,右键,选择“加载至虚拟光驱” 3. 打开“CD驱动器

HDU 2473 Junk-Mail Filter (并查集节点删除)

Junk-Mail Filter Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7254    Accepted Submission(s): 2307 Problem Description Recognizing junk mails is a tough task. The method used here consists o