题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2473

Junk-Mail Filter

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5343    Accepted Submission(s): 1702

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 whether the email is a spam.

We want to extract the set of common characteristics from the N sample junk emails available at the moment, and thus having a handy data-analyzing tool would be helpful. The tool should support the following kinds of operations:

a) “M X Y”, meaning that we think that the characteristics of spam X and Y are the same. Note that the relationship defined here is transitive, so
relationships (other than the one between X and Y) need to be created if they are not present at the moment.

b) “S X”, meaning that we think spam X had been misidentified. Your tool should remove all relationships that spam X has when this command is received; after that, spam X will become an isolated node in the relationship graph.

Initially no relationships exist between any pair of the junk emails, so the number of distinct characteristics at that time is N.
Please help us keep track of any necessary information to solve our problem.

Input
There are multiple test cases in the input file.
Each test case starts with two integers, N and M (1 ≤ N ≤ 105 , 1 ≤ M ≤ 106), the number of email samples and the number of operations. M lines follow, each line is one of the two formats described above.
Two successive test cases are separated by a blank line. A case with N = 0 and M = 0 indicates the end of the input file, and should not be processed by your program.
Output
For each test case, please print a single integer, the number of distinct common characteristics, to the console. Follow the format as indicated in the sample below.
Sample Input
5 6 M 0 1 M 1 2 M 1 3 S 1 M 1 2 S 3 3 1 M 1 2 0 0
Sample Output
Case #1: 3 Case #2: 2

分析:

本题考查的是并查集的删除.

在删除结点的时候要注意这样的问题: 并查集的结构是一棵树,当把某一个结点删去(将其父结点置为自己)时,它的子结点的根就会丢失.因此,在删除某结点的时候,要确定它的所有子结点都已经并到根上了.

解决方法: 为每一个结点加一个虚根,这样每个结点都是叶子结点.插入结点时,把它们都并到虚根的集合中.删除结点时,只要把它的父结点置为一个无用的虚根,找个点顶替要删除的点,就行了。

代码如下:

#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <vector>
#include<set>
using namespace std;
typedef long long ll;
#define N 1100010
int extra;
struct Node
{int father;int replace;
};
Node node[N];
//为每一个节点加一个虚根,这样每个节点都是叶子节点,
void init(int n)  // n为节点个数
{int i;for(i=0;i<n;i++)   // 下标从0开始
    {node[i].father=i;node[i].replace=i;}extra=n;   // 虚拟节点
}
int find(int x)
{return node[x].father!=x?node[x].father=find(node[x].father):node[x].father;
}
//插入节点时,把他们都并到虚根的集合中
void Union(int x,int y)
{int xx=find(x),yy=find(y);if(xx!=yy)node[xx].father=yy;
}//删除节点时,只要把他的父节点置为一个无用的虚根
void deleteX(int x)
{node[x].replace=extra;node[node[x].replace].father=extra;extra++;
}
int main()
{int n,m,k=1,x,y,sum;char c[2];while(scanf("%d%d",&n,&m),n||m){init(n);for(int i=0;i<m;i++){scanf("%s",c);if(c[0]=='M'){scanf("%d%d",&x,&y);Union(node[x].replace,node[y].replace);}else{scanf("%d",&x);deleteX(x);}}set<int>ans;         // 计算集合的个数用set
        ans.clear();for(int i=0;i<n;i++){int temp=find(node[i].replace);ans.insert(temp);}printf("Case #%d: %d\n",k++,ans.size());}return 0;
}

转载于:https://www.cnblogs.com/zn505119020/p/3619511.html

并查集 删除节点 求集合的个数set hdu 2473相关推荐

  1. PAT甲级1021 Deepest Root :[C++题解]树的最大深度、并查集、dfs求树的深度

    文章目录 题目分析 题目链接 题目分析 分析: 考察知识点:并查集.dfs.树的深度 给定n个结点,n-1条边,只要能保证只有1个连通分量,就是一棵树.否则的话就不是树,它是不连通的. 用并查集来看是 ...

  2. 并查集板子:acwing836. 合并集合

    文章目录 并查集原理 并查集代码实现 并查集原理 并查集的常用操作: 将两个集合合并 询问两个元素是否在同一个集合中 并查集在近乎O(1)的时间内完成以上两个操作. 基本原理:每个集合用一棵树表示.树 ...

  3. poj 2985(并查集+线段树求K大数)

    解题思路:这道题并查集很容易,合并时找到父节点就直接加上去就ok了.关键是如何求K大数,我一直在想用线段树怎么写,一开始想如果直接记录数的大小那肯定是没戏了,借鉴了一下别人的思路:区间[a,b]记录的 ...

  4. hdu 2473(并查集+删除操作)

    解题思路:这道题有并查集的删除操作,如果直接对这一棵树进行删除节点操作肯定是很困难的.所以可以建立虚拟节点,只要有一个节点要被删除,就直接把它投影到虚拟节点上,即用这个虚拟节点来代替我们要删除的节点. ...

  5. POJ2186——并查集+Tarjan算法求强连通分量

    算法讨论:这题陷阱比较多.首先,被所有牛欢迎,这说明所有的牛都要在一个连通图中,也就是将所给的边看成无向边的时候,所有点要在一个连通图中.这个我们用并查集来实现就可以了.强连通分量的求法就很简单了,正 ...

  6. 图论500题 ---- 并查集+树形dp+枚举 求解动态的最小生成树 HDU 4126

    题目链接 题目大意: 给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边(可以经过可疑边新的花费构建的边),注意每次只出现一条 ...

  7. 数据结构与算法——并查集(不相交集合)

    文章目录 认识并查集 并查集解析 基本思想 如何查看a,b是否在一个集合? a,b合并,究竟是a的祖先合并在b的祖先上,还是b的祖先合并在a上? 其他路径压缩? 代码实现 结语 认识并查集 对于并查集 ...

  8. vb6实现union数据结构_数据结构与算法——并查集(不相交集合)

    首发公众号:bigsai 认识并查集 对于并查集(不相交集合),很多人会感到很陌生,没听过或者不是特别了解.实际上并查集是一种挺高效的数据结构.实现简单,只是所有元素统一遵从一个规律所以让办事情的效率 ...

  9. 信息传递(带权并查集求最小环

    P2661 [NOIP2015 提高组] 信息传递 题意: nnn 个同学玩信息传递,第 iii 个同学只会将信息传递给同学 TiT_iTi​,游戏开始时每个人只知道自己的生日,一轮游戏同学 iii ...

最新文章

  1. python开源项目贡献_通过为开源项目做贡献,我如何找到理想的工作
  2. 面试官:说说Kafka处理请求的全流程
  3. 独家 | 17篇手把手教技术指南、技术进阶干货大合集
  4. 【WPF】屏幕右下角消息提示框
  5. 北京师范大学网络教育期末考试计算机,北京师范大学网络教育———《计算机应用基础》第二章同步练习题(4)...
  6. mysql复制的配置
  7. SAP ABAP实用技巧介绍系列之 How is configuration data loaded
  8. mysql五-1:单表查询
  9. 机器学习理论引导 电子版_机器学习理论篇1:机器学习的数学基础(2)
  10. 初创公司 经营_LibreCorps指导人道主义初创公司如何运行开源方式
  11. zoj 3629 Treasure Hunt IV
  12. JAVA编程思想——读书笔记 对象的容纳
  13. webtrends之ODBC源数据获取(二)——ACCESS访问篇
  14. 浏览器是如何工作的:Chrome V8让你更懂JavaScript
  15. led屏背后线路安装图解_LED屏安装工程施工方案
  16. GPU共享方案 显卡无用了
  17. 2022年11月编程语言流行度排名
  18. 计算机网络的结构有,计算机网络的组成部分是什么,其各自都有什么功能
  19. dpdk加速网络协议栈ANS用户手册
  20. CAD 二次开发 图层操作(1)创建图层

热门文章

  1. linux实用的日志分析脚本
  2. 3140: [Hnoi2013]消毒
  3. 配置了tomcat,更改了默认端口为8070,还是访问不了
  4. win7开放80端口
  5. 表主键自增长Mybatis插入数据报错
  6. mysql 数据库的 导入于导出
  7. a new weekday
  8. 矩形覆盖-----批了外皮的亲蛙跳
  9. 母版页的铵钮事件去获取子页的内容
  10. html 5 新增标签及简介