hdu 2473 Junk-Mail Filter(并查集_虚节点)2008 Asia Regional Hangzhou
感觉有些难的题,刚开始就想到了设立虚节点,但是实现总是出错,因为每次设立了虚节点之后,无法将原节点和虚节点分开,导致虚节点根本无意义。
以上纯属废话,可以忽略……
题意——
给定n个点(0, 1, 2, ..., n-1),可进行两种操作:1. 将两个点合并到一个集合中; 2. 将一个点从原有集合中取出。问最后点有几个集合。
很明显的并查集,包含合并,删除操作。
但是,删除某节点的时候,需要保证这个集合中,除了被删除节点的其它节点不变,这点有些难以处理。
我们知道,并查集其实是一棵棵树,我们将树中某节点删除,还要保证树的结构不变,可以采用一种方法,那就是“虚节点”,也就是说,我们并不删除那个节点,却将需要删除的节点中保存的数据转移到一个新的节点中,这个节点独立于这棵树之外。这样一来,我们查询那个节点的时候,会查询到新的节点,而原本的节点的作用仅仅是保持树的结构。
因此,我们需要两个数组,一个数组是fm[N+M],一个数组是fle[N],其中fle[]数组的fle[i]表示第i个节点的值,而fm[]数组中,fm[fle[i]]用来保存第i个节点的前驱,即fle[i]的父节点。
重点就在于这个fle[],每次删除节点i时,我们不改变fm[fle[i]],这样树的结构就不会变,而我们赋予fle[i]一个从未使用过的新值,就使实际上的i节点变化了。
这样每次删除i节点,都只需要赋予fle[i]一个从未用过的新值,类似于给i节点换一个新马甲,就可以解决问题。
我们可以从值为n开始,给节点赋的值依次为n++,这样,因为最多M次操作,那么最多换M个马甲,因此,fm的大小为M+N。
上代码——
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; const int N = ;
const int M = ; bool vis[N+M];
int fm[N+M], fle[N];
int n, m, a, b, pt, ans, tm;
char s[]; void init()
{
for(int i = ; i < n; i++)
{
fm[i] = i;
fle[i] = i;
}
memset(vis, , sizeof(vis));
pt = n;
ans = ;
} int mfind(int a)
{
int fa = a; while(fa != fm[fa]) fa = fm[fa];
while(a != fm[a])
{
int mid = fm[a];
fm[a] = fa;
a = mid;
}
return fa;
} void mmerge()
{
int fa = mfind(fm[fle[a]]);
int fb = mfind(fm[fle[b]]);
if(fa != fb) fm[fa] = fb;
} void dmerge()
{
fle[a] = pt; //换马甲
fm[pt] = pt; //给这个新值初始化父节点
pt++; //为新马甲做准备
} void work()
{
while(m--)
{
scanf("%s", s);
if(s[] == 'M')
{
scanf("%d%d", &a, &b);
mmerge();
}
else if(s[] == 'S')
{
scanf("%d", &a);
dmerge();
}
} for(int i = ; i < n; i++)
{
int ance = mfind(fle[i]);
if(!vis[ance])
{
ans++;
vis[ance] = ;
}
}
printf("Case #%d: %d\n", tm++, ans);
} int main()
{
//freopen("test.in", "r", stdin);
tm = ;
while(~scanf("%d%d", &n, &m) && (n+m))
{
init();
work();
}
}
ps: 这几天状态一直不好,但是今天突然看见一句话,感由心生,终于耐下心来弄明白了这道题——心若没有栖息的地方,在哪里都是流浪
继续加油吧……
hdu 2473 Junk-Mail Filter(并查集_虚节点)2008 Asia Regional Hangzhou的更多相关文章
- HDU 2492 Ping pong(数学+树状数组)(2008 Asia Regional Beijing)
Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street ...
- HDU 2491 Priest John's Busiest Day(贪心)(2008 Asia Regional Beijing)
Description John is the only priest in his town. October 26th is the John's busiest day in a year be ...
- hdu 2473 Junk-Mail Filter (并查集之点的删除)
Junk-Mail Filter Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- 《程序员代码面试指南》第三章 二叉树问题 Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题
题目待续.... Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题 java代码
- HDU 2473 Junk-Mail Filter 并查集,虚拟删除操作
http://acm.hdu.edu.cn/showproblem.php?pid=2473 给定两种操作 第一种是合并X Y 第二种是把X分离出来,就是从原来的集合中分离出来,其它的关系不变. 关键 ...
- HDU 2473 Junk-Mail Filter(并查集的删除操作)
题目地址:pid=2473">HDU 2473 这题曾经碰到过,没做出来. .如今又做了做,还是没做出来. ... 这题涉及到并查集的删除操作.想到了设一个虚节点,可是我把虚节点设为了 ...
- 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~ ...
- HDU 2473 Junk-Mail Filter(并查集+删点,设立虚父节点/找个代理)
题意:有N封邮件, 然后又两种操作,如果是M X Y , 表示X和Y是相同的邮件.如果是S X,那么表示对X的判断是错误的,X是不属于X当前所在的那个集合,要把X分离出来,让X变成单独的一个.最后问集 ...
- (step5.1.2)hdu 2473(Junk-Mail Filter——并查集)
题目大意:输入两个整数n,m(n表示点的个数,m表示操作数).在接下来的m行中,对点的操作有两种 1)M a b . 表示将a.b并到一个集合中 2)S a .表示将a从原来的集合中去除,而成为一个单 ...
随机推荐
- Oracle 6 - 锁和闩 - transaction的可串行化
本文主要内容 1.transaction的可串行化 2.数据库并发带来的问题, dirty read, Nonrepeatable reads, Phantoms幻读 3.隔离级别和2中的问题 4. ...
- 李洪强iOS开发之OC[013] -类的创建的练习
// // main.m // 12 - 类的创建练习 // // Created by vic fan on 16/7/9. // Copyright © 2016年 李洪强. All ri ...
- java工具类系列 (四.SerializationUtils)
java工具类系列 (四.SerializationUtils) SerializationUtils该类为序列化工具类,也是lang包下的工具,主要用于序列化操作 import java.io.Se ...
- iOS 开发--开源图片处理圆角
概述 开源项目名称:HYBImageCliped 当前版本:2.0.0 项目用途:可给任意继承UIView的控件添加任意多个圆角.可根据颜色生成图片且可带任意个圆角.给UIButton设置不同状态下的 ...
- Photoshop:模拟钢笔压力
预期效果: 方法: 按B选择画笔工具,设置"钢笔压力" 路径描边:选择路径,右击路径,选择“描边路径” 或在路径面板,选择: 即可得到预期效果!
- C# 任意类型数据转JSON格式(转)
HOT SUMMER 每天都是不一样,积极的去感受生活 C# 任意类型数据转JSON格式 /// <summary> /// List转成json /// </summary> ...
- arcengine C# 读写lyr(转)
写lyr { IFeatureLayer LineLayer = axMapControl1.get_Layer(0) as IFeatureLayer; ILayerFile ...
- C++:对象指针
对象指针概念:每一个对象在初始化后都会在内存中占有一定的空间.因此,既可以通过对象名访问, 也可以通过一个对象地址来访问一个对象.对象指针就是用于存放对象地址的变量. 声明对象指针的一般语法格式为:类 ...
- UML与数据流图
Ref: <数据库设计理论及应用(3)——需求分析及数据>http://wenku.baidu.com/link?url=hbhJFytMKT8A ...
- 轻量级MVC标准
看到标题,估计有人就开始想吐了,没关系,你可以先吐完再看,现在MVC框架多如牛毛,没必要再重复发明轮子了,要声明的是,这里不是想要发明轮子,也没那个闲工夫去发明轮子,而是看到这么多MVC框架模样都差不 ...