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从原来的集合中去除,而成为一个单 ...
随机推荐
- 【设计模式六大原则2】里氏替换原则(Liskov Substitution Principle)
肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:如果对 ...
- Create a method synchronized without using synchronized keyword
Actually, lots of ways: No need for synchronization at all if you don't have mutable state. No need ...
- 如何在windows环境中搭建apache+subversion(ZT)
我一直有一个想法就是在本机上象scm一样的搭建一个subversion服务器,然后每天写完代码的时候提交一下,这种感觉好好哦,之前我在windows环境中搭建过纯subversion的服务器兴奋过一阵 ...
- Ping 命令
Ping”命令是我们在判断网络故障常用的命令 它是用来检查网络是否通畅或者网络连接速度的命令. 它所利用的原理是这样的:网络上的机器都有唯一确定的IP地址,我们给目标IP地址发送一个数据包, 对方就要 ...
- JavaScript之this,new,delete,call,apply(转)
JavaScript之this,new,delete,call,apply 1.this 一般而言,在Javascript中,this指向函数执行时的当前对象. 2.new 在JavaScript中, ...
- MVC5中Model层开发数据注解
ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证(在服务器端和客户端验证数据的有效性) 数 ...
- sql 随笔 2015-07-02
sql 自定义函数 --检查函数是否存在 if exists (select * from dbo.sysobjects where id = object_id(N'dbo.pTitleCase') ...
- Linux设备管理之权限倾斜——mem、proc、devfs、sysfs、udev(下)
linux发展第一阶段 01devfs(linux2.6之前) 02udev(用户空间) 03sysfs(linux2.6之后,描述设备属性) linux发展第二阶段 01sysfs+udev(ude ...
- iosblock用法
看了很多的block用法,还是小糊涂. 最后还是自己尝试吧. #import "FirstViewController.h" @interface FirstViewControl ...
- myeclipse2014破解版本链接
myeclipse2014破解版本下载链接 http://www.my-eclipse.cn/#download myeclipse2014破解版本汉化链接 https://blog.my-eclip ...