【题目】:(地址:)

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97671#problem/E

【题意】:

给出多棵树和两类操作:操作(C  x)删除结点 x 与其父结点的连边;操作(Q a b)询问 a b 是否连通。

【解题思路】:

连通性的查询容易想到用并查集,关键在于如何处理删边。

考虑到删边的难点在于查询时的路径压缩导致某些结点与其父结点"不直接相连",这里使用离线处理,在查询之前把所有该删的边删除,同时逆序处理询问操作;当逆序处理到删边操作时,复原删掉的边(删除变为增边)。

【代码】:(上了个比较标准的并查集模板)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<algorithm>
#define LL long long
#define maxn 25000
#define IN freopen("in.txt","r",stdin);
using namespace std; struct Union_Find_Set{ int fa[maxn]; /*每个结点的父亲节点编号*/
int rank[maxn]; /*树的高度*/ /*构造并查集并初始化*/
void make_set()
{
for(int i=; i<maxn; i++){
fa[i] = i; /*初始时本身构成一个集合,根为本身*/
rank[i] = ;
}
} /*递归查找结点所在树的根节点*/
int find_set(int x)
{
/*路径压缩*/
return x!=fa[x]? fa[x]=find_set(fa[x]) : x;
} /*合并两个集合*/
void unite_set(int x, int y)
{
x = find_set(x);
y = find_set(y);
/*记录树的高度防止合并后退化,rank小的向rank大的连接*/
if(rank[x] < rank[y]) swap(x,y);
fa[y] = x; /*合并*/
if(rank[x] == rank[y]) rank[x]++; /*高度相同则加1*/
} /*判断两结点是否属于同一集合*/
bool same_set(int x, int y)
{
return find_set(x) == find_set(y);
}
}UFS; int n,q;
struct node{
char type;
int first, second;
}; stack<node> s;
stack<bool> ans; int main(int argc, char const *argv[])
{
//IN; int t,ca=;scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&q); while(!s.empty()) s.pop();
while(!ans.empty()) ans.pop();
UFS.make_set(); for(int i=; i<=n; i++){
scanf("%d",&UFS.fa[i]);
if(!UFS.fa[i]) UFS.fa[i] = i;
} for(int i=; i<=q; i++)
{
node tmp_node;
getchar();
scanf("%c",&tmp_node.type);
if(tmp_node.type=='Q'){
scanf("%d %d",&tmp_node.first, &tmp_node.second);
}
else{
scanf("%d",&tmp_node.first);
tmp_node.second = UFS.fa[tmp_node.first];
/*离线处理--询问之前删边,避免路径压缩导致删边失效*/
UFS.fa[tmp_node.first] = tmp_node.first;
}
s.push(tmp_node);
} while(q--)
{
node tmp_node = s.top(); s.pop(); if(tmp_node.type=='Q'){
if(UFS.same_set(tmp_node.first, tmp_node.second)) ans.push();
else ans.push();
}
else{
UFS.fa[tmp_node.first] = tmp_node.second;
}
} printf("Case #%d:\n", ca++);
while(!ans.empty())
{
if(ans.top() == ) puts("YES");
else puts("NO");
ans.pop();
}
} return ;
}

UVALive 6910 Cutting Tree(离线逆序并查集)的更多相关文章

  1. UVALive - 6910 (离线逆序并查集)

    题意:给处编号从1~n这n个节点的父节点,得到含有若干棵树的森林:然后再给出k个操作,分两种'C x'是将节点x与其父节点所连接的支剪短:'Q a b'是询问a和b是否在同一棵树中. 题解:一开始拿到 ...

  2. UVALive 6910 Cutting Tree(并查集应用)

    总体来说,这个题给的时间比较长,样例也是比较弱的,别的方法也能做出来. 我第一次使用的是不合并路径的并查集,几乎是一种暴力,花了600多MS,感觉还是不太好的,发现AC的人很多都在300MS之内的过得 ...

  3. UVALive 6910 Cutting Tree 并查集

    Cutting Tree 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8& ...

  4. ZOJ-3261 Connections in Galaxy War---离线操作+逆序并查集

    题目链接: https://cn.vjudge.net/problem/ZOJ-3261 题目大意: 给你一些点,还有一些边,每个点上都有一个权值,然后有一些询问,分为两种,query a 询问与a直 ...

  5. Connections in Galaxy War ZOJ - 3261 离线操作+逆序并查集 并查集删边

    #include<iostream> #include<cstring> #include<stdio.h> #include<map> #includ ...

  6. hdu 5441 Travel 离线带权并查集

    Travel Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5441 De ...

  7. hdu 5441 travel 离线+带权并查集

    Time Limit: 1500/1000 MS (Java/Others)  Memory Limit: 131072/131072 K (Java/Others) Problem Descript ...

  8. LCA(最近公共祖先)离线算法Tarjan+并查集

    本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...

  9. Tree Restoration Gym - 101755F (并查集)

    There is a tree of n vertices. For each vertex a list of all its successors is known (not only direc ...

随机推荐

  1. 【C#设计模式——创建型模式】抽象工厂模式

    抽象工厂模式比工厂模式具有更高层次的抽象性.当要返回一系列相关类中的某一个,而每个类都能根据需要返回不同的对象时,可以选择这种模式.直接进入示例. 示例描述:完成花园的规划,多种花园种类,每个里面多种 ...

  2. MyBatis学习总结(5)——实现关联表查询

    一对一关联 提出需求 根据班级id查询班级信息(带老师的信息) 创建表和数据 创建一张教师表和班级表,假设一个老师负责教一个班,那么老师和班级之间的关系就是一对一的关系. create table t ...

  3. oracle视图总结(转)

    视图简介: 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改.视图基于的表称为基表.视图是存储在数据字典里的一条select语句. 通过创建视图可以提取数 ...

  4. "=="和equals方法的区别

    .==和equal .栈内存和对内存 单独把一个东西说清楚,然后再说清楚另一个,这样,它们的区别自然就出来了,混在一起说,则很难说清楚) ==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量 ...

  5. 转:ASP.NET MVC中Unobtrusive Ajax的妙用

    Unobtrusive Javascript有三层含义:一是在HTML代码中不会随意的插入Javsscript代码,只在标签中加一些额外的属性值,然后被引用的脚本文件识别和处理:二是通过脚本文件所增加 ...

  6. OK335xS psplash make-image-header.sh hacking

    /***************************************************************************** * OK335xS psplash mak ...

  7. busybox filesystem add ldd function

    /******************************************************************** * busybox filesystem add ldd f ...

  8. Mysql,SqlServer,Oracle主键自动增长的设置

    1.把主键定义为自动增长标识符类型 MySql 在mysql中,如果把表的主键设为auto_increment类型,数据库就会自动为主键赋值.例如: )); insert into customers ...

  9. django - settings

    1.doc - https://docs.djangoproject.com/en/1.6/topics/settings/ from django.conf import settings # 加载 ...

  10. NALU(NAL单元)

    一 NALU类型    标识NAL单元中的RBSP数据类型,其中,nal_unit_type为1, 2, 3, 4, 5及12的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL ...