Junk-Mail Filter 【并查集虚父节点】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2473
题目大意:
n个点,m个操作,操作时,输入M a b,表示a, b在一个集合里, 输入S a 表示将a从集合里删除掉。求最后有多少个不同的集合。
解题思路:
需要删除结点,但是并非是删除与该节点为父亲节点的子树,而仅仅是该点。所以需要用到虚父节点。
所以再开一个数组,更新节点时直接改变当前节点的父节点,使其等于大于n的父节点,这样就把其节点删除了。
代码如下:
#include<iostream>
#include<string.h>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int MAXN = 1e6 + ; int n, m, temp, k;
char op;
int p[MAXN], pre[MAXN], flag[MAXN]; int find(int x)
{
if(pre[x] == x)
return x;
else
{
int root = find(pre[x]);
pre[x] = root;
return pre[x];
}
} int main()
{
cin.sync_with_stdio(false);
k = ;
while(cin >> n >> m)
{
if(n == && m == )
break;
temp = n, mem(flag, );
for(int i = ; i < n; i ++)
{
pre[i] = i;
p[i] = i; //虚设
}
for(int i = ; i <= m; i++)
{
cin >> op;
if(op == 'M')
{
int a, b;
cin >> a >> b;
int x = find(p[a]), y = find(p[b]);
if(x != y)
pre[y] = x;
}
else
{
int a;
cin >> a;
p[a] = temp;
pre[temp] = temp;
temp ++;
}
}
int ans = ;
for(int i = ; i < n; i ++)
{
int x = find(p[i]);
if(!flag[x])
{
ans ++;
flag[x] = ;
}
}
cout << "Case #" << k ++ << ": " << ans << endl;
}
return ;
}
同样有一道一样题,更加直观。
乱世天下,诸侯割据。每个诸侯王都有一片自己的领土。但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土 面积不断扩大。而实力弱的诸侯王为了不让自己的领土被吞并,他会联合一些其他同样弱小的诸侯国,组成联盟(联盟不止一个),来共同抵抗那些强大的诸侯国。 强大的诸侯国为了瓦解这些联盟,派出了最优秀的间谍来离间他们,使一些诸侯国退出联盟。最开始,每个诸侯国是一个联盟。
有两种操作
1、U x y 表示x和y在同一个联盟。(0≤x,y<n)
2、D x 表示x退出联盟。 仅仅是x退出联盟,对于其他的诸侯国没有影响。因此是删除单个点而不是子树。
- 输入
- 多组测试数据
第一行两个数,n和m(1 ≤ n≤ 10^5, 1 ≤ m ≤10^5),分别表示诸侯国的个数和操作次数。
接下来有m行操作 - 输出
- 输出联盟的个数
- 样例输入
-
5 7
-
U 0 1
-
U 1 2
-
U 0 3
-
D 0
-
U 1 4
-
D 2
-
U 0 2
-
10 1
-
U 0 9
- 样例输出
-
Case #1: 2
-
Case #2: 9
#include<iostream>
#include<string.h>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int MAXN = 1e5 + ; int n, m, temp, k;
char op;
int p[MAXN], pre[ * MAXN], flag[ * MAXN]; int find(int x)
{
if(pre[x] == x)
return x;
else
{
int root = find(pre[x]);
pre[x] = root;
return pre[x];
}
} int main()
{
cin.sync_with_stdio(false);
k = ;
while(cin >> n >> m)
{
temp = n, mem(flag, );
for(int i = ; i < n; i ++)
{
pre[i] = i;
p[i] = i; //虚设
}
for(int i = ; i <= m; i++)
{
cin >> op;
if(op == 'U')
{
int a, b;
cin >> a >> b;
int x = find(p[a]), y = find(p[b]);
if(x != y)
pre[y] = x;
}
else
{
int a;
cin >> a;
p[a] = temp;
pre[temp] = temp;
temp ++;
}
}
int ans = ;
for(int i = ; i < n; i ++)
{
int x = find(p[i]);
if(!flag[x])
{
ans ++;
flag[x] = ;
}
}
cout << "Case #" << k ++ << ": " << ans << endl;
}
return ;
}
Junk-Mail Filter 【并查集虚父节点】的更多相关文章
- HDU 2473 Junk-Mail Filter(并查集+删点,设立虚父节点/找个代理)
题意:有N封邮件, 然后又两种操作,如果是M X Y , 表示X和Y是相同的邮件.如果是S X,那么表示对X的判断是错误的,X是不属于X当前所在的那个集合,要把X分离出来,让X变成单独的一个.最后问集 ...
- HDU2473 Junk-Mail Filter - 并查集删除操作(虚父节点)
传送门 题意: 每次合并两份邮件,或者将某一份邮件独立出来,问最后有多少个邮件集合. 分析: 考虑初始化每个节点的祖先为一个虚父节点(i + n),虚父节点指向它自己.这样可以进行正常的合并操作. 而 ...
- 《程序员代码面试指南》第三章 二叉树问题 Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题
题目待续.... Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题 java代码
- hdu2473 Junk-Mail Filter 并查集+删除节点+路径压缩
Description Recognizing junk mails is a tough task. The method used here consists of two steps: 1) ...
- hdu 2473 Junk-Mail Filter (并查集之点的删除)
Junk-Mail Filter Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 2473 Junk-Mail Filter(并查集的删除操作)
题目地址:pid=2473">HDU 2473 这题曾经碰到过,没做出来. .如今又做了做,还是没做出来. ... 这题涉及到并查集的删除操作.想到了设一个虚节点,可是我把虚节点设为了 ...
- (step5.1.2)hdu 2473(Junk-Mail Filter——并查集)
题目大意:输入两个整数n,m(n表示点的个数,m表示操作数).在接下来的m行中,对点的操作有两种 1)M a b . 表示将a.b并到一个集合中 2)S a .表示将a从原来的集合中去除,而成为一个单 ...
- HDU 2473 Junk-Mail Filter 并查集,虚拟删除操作
http://acm.hdu.edu.cn/showproblem.php?pid=2473 给定两种操作 第一种是合并X Y 第二种是把X分离出来,就是从原来的集合中分离出来,其它的关系不变. 关键 ...
- HDU 2473 Junk-Mail Filter 并查集删除(FZU 2155盟国)
http://acm.hdu.edu.cn/showproblem.php?pid=2473 http://acm.fzu.edu.cn/problem.php?pid=2155 题目大意: 编号0~ ...
随机推荐
- for迭代多个对象
1.传统方法 from random import randint chinese = [randint(60, 100) for _ in range(40)] math = [randint(60 ...
- Vue 组件中锚点定位的问题
1 当前组件的顶部 this.$el.scrollIntoView() 2 指定的 Element this.$el.querySelector(selector).scrollIntoView() ...
- MySQL数据分析实战-朱元禄-专题视频课程
MySQL数据分析实战-496人已学习 课程介绍 本套课程由知名数据分析博主jacky老师录制,深入浅出讲解MySQL数据分析,从实战角度出发,帮助大家制胜职场!课程收益 1.学会 ...
- windows环境下启动mongodb服务
方法一1.打开命令窗口,切换到mongodb安装目录下的“bin”目录中. 输入命令:cd E:\software\MongoDB\Server\3.4\bin 2.启动服务.输入命令:”mongod ...
- POI的XWPFTableCell的方法
1. XWPFParagraph addParagraph() 在这个表格单元格中添加一个段落 2. void addParagraph(XWPFParagraph p) 给这个表格加一段 3. ja ...
- C语言和Python语言在存储变量方面的不同
C语言和Python语言在存储变量方面的不同 众所周知,Python是脚本语言,边解释边执行,而C语言是编译型语言 存储变量: C语言定义变量,变量本身代表的就是大小,任何一个字母或者数字 符号均可以 ...
- P3015 [USACO11FEB]最好的括号Best Parenthesis
P3015 [USACO11FEB]最好的括号Best Parenthesis 题解 一定要开 long long !!! 通过阅读英文题面我们知道所给出的字符串是已经匹配好的,所以我们只是计算就好了 ...
- 4 个独特的 Linux 终端模拟器(转)
4 个独特的 Linux 终端模拟器 译自:https://www.linux.com/blog/learn/2018/12/4-unique-terminals-linux作者: Jack Wall ...
- CXF框架构建和开发 Services
Apache CXF 是一个开源的 Services 框架,CXF 帮助您来构建和开发 Services 这些 Services 可以支持多种协议,比如:SOAP.POST/HTTP.RESTful ...
- 为什么使用 Web Services?
最重要的事情是协同工作 由于所有主要的平台均可通过 Web 浏览器来访问 Web,不同的平台可以借此进行交互.为了让这些平台协同工作,Web 应用程序被开发了出来. Web 应用程序是运行在 Web ...