此题最难处理的操作就是将一个单点改变集合,而普通的并查集是不支持这种操作的。

当结点p是叶子结点的时候,直接pa[p] = root(q)是可以的,

p没有子结点,这个操作对其它结点不会造成任何影响,

而当p是父结点的时候这种操作会破坏子节点的路径,因此必须保留原来的路径。

我们希望pa[p] = root(q)的同时又保留原来的路径,那么只需要在点上做一个标记,

如果这个点被标记,就沿着新的路径寻找。

此时在修改操作的时候这个点一定是叶子结点,所以可以直接pa[p] = root(q),

而原来的点则变成一个虚点用来保留了原来的路径。

改变集合的操作以及查询都只涉及到单点,这个标记只影响这个点,在二次以及以上的寻找还是要按照原来的路径。

#include<bits/stdc++.h>
using namespace std; const int maxn = 1e5+;
int fa[maxn],fa2[maxn],cnt[maxn],sum[maxn];
bool fg[maxn];
int Find(int x,bool d) {
if(fg[x]&&d) return Find(fa2[x],false);
return x==fa[x]?x:fa[x]=Find(fa[x],false);
}
int main()
{
//freopen("in.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&n,&m)){
for(int i = ; i <= n; i++) fa[i]=i,fg[i]=false,cnt[i]=,sum[i]=i;
while(m--){
int op,p,q; scanf("%d%d",&op,&p);
if(op!=){
scanf("%d",&q);
int x = Find(p,true), y = Find(q,true);
if(op == ){
if(x!=y){
cnt[y] += cnt[x];
sum[y] += sum[x];
fa[x] = y;
}
}else {
if(x!=y){
cnt[x]--,sum[x]-=p;
cnt[y]++,sum[y]+=p;
fg[p] = true;
fa2[p] = y;
}
}
}else {
int x = Find(p,true);
printf("%d %d\n",cnt[x],sum[x]);
}
}
}
return ;
}

UVA 11987 Almost Union-Find (单点修改的并查集)的更多相关文章

  1. UVA - 11987 Almost Union-Find(带删除的并查集)

    I hope you know the beautiful Union-Find structure. In this problem, you’re to implement something s ...

  2. Uva 10596 - Morning Walk 欧拉回路基础水题 并查集实现

    题目给出图,要求判断不能一遍走完所有边,也就是无向图,题目分类是分欧拉回路,但其实只要判断度数就行了. 一开始以为只要判断度数就可以了,交了一发WA了.听别人说要先判断是否是联通图,于是用并查集并一起 ...

  3. Mutual Training for Wannafly Union #6 E - Summer Trip(并查集)

    题目链接:http://www.spoj.com/problems/IAPCR2F/en/ 题目大意: 给m个数字代表的大小,之后n组数据,两两关联,关联后的所有数字为一组,从小到大输出组数以及对应的 ...

  4. uva live 7638 Number of Connected Components (并查集)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  5. UVA 11987 Almost Union-Find 并查集单点修改

                                     Almost Union-Find I hope you know the beautiful Union-Find structur ...

  6. UVA - 11987 Almost Union-Find[并查集 删除]

    UVA - 11987 Almost Union-Find I hope you know the beautiful Union-Find structure. In this problem, y ...

  7. POJ 3321 Apple Tree(DFS序+线段树单点修改区间查询)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 25904   Accepted: 7682 Descr ...

  8. 线段树:Segment Tree(单点修改/区间修改模板) C++

    线段树是非常有效的数据结构,可以快速的维护单点修改,区域修改,查询最大值,最小值等功能. 同时,它也很重要.如果有一天比赛,你卡在了一道线段树模板题目上,这就真的尴尬了.不过,随着时代的进步,题目也越 ...

  9. UVA 11987 - Almost Union-Find(并查集)

    UVA 11987 - Almost Union-Find 题目链接 题意:给定一些集合,操作1是合并集合,操作2是把集合中一个元素移动到还有一个集合,操作3输出集合的个数和总和 思路:并查集,关键在 ...

随机推荐

  1. PostgreSQL 务实应用(五/5)常用表达

    在实际应用中,对于具体的数据计算我们会找相应的函数来实现.而计算需求不同的表达,往往会使得我们使用不同的函数或方式来实现.或者也可以说,同一计算可以使用多种不同的表达方式实现. PostgreSQL ...

  2. PHP正则表达式,看这一篇就够啦!

    前言 不知道你们有没有这个感觉,看正则表达式就像看天文数字一样,什么电话号码.邮箱的正则表达式,上网复制一下粘贴下来就搞定了.完全不知道这写的是什么玩意.后来我自己也想学一下,因为感觉用处还是挺大的. ...

  3. lower_bound和upper_bound使用说明

    #include <bits/stdc++.h> using namespace std; int main() { ]; ;i<=;i++) { a[i] = i*; } ;i&l ...

  4. 51nod1112(xjb)

    題目鏈接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1112 題意:中文題誒- 思路:對於函數 f(x) = a + ...

  5. 洛谷P4768 [NOI2018]归程(克鲁斯卡尔重构树+最短路)

    传送门 前置技能,克鲁斯卡尔重构树 我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树 那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价) 可以一开始直接 ...

  6. 基于react+如何搭建一个完整的前端框架(1)

      1.使用 create-react-app 快速构建 React 开发环境 create-react-app 是来自于 Facebook,通过该命令我们无需配置就能快速构建 React 开发环境. ...

  7. mCustomScrollbar 滚动条的使用

    前两天需要设置滚动条的样式,一开始我以为只是用css设置就可以了,嗯,果然还是想的很简单,虽然可以在css设置滚动条样式,但是只是在火狐,IE浏览器上根本就不能用,所以只能使用js插件来设置滚动条的属 ...

  8. Netty源码分析(七):初识ChannelPipeline

    ChannelPipeline单看名称就可以知道Channel的管道.本篇将结合它的默认实现类DefaultChannelPipeline来对它做一个简单的介绍. 示例图 上图是官方提供的Channe ...

  9. 分布式集群环境下,如何实现session共享一(应用场景)

    在web应用中,由于http的请求响应式,无状态.要记录用户相关的状态信息,比如电商网站的购物车,比如用户是否登录等,都需要使用session.我们知道session是由servlet容器创建和管理, ...

  10. Arrange the Bulls

    题目链接 #include <stdio.h> #include <algorithm> #include <string.h> #include <iost ...