【题目】:(地址:)

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. lightOJ 1132 Summing up Powers(矩阵 二分)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1132 题意:给出n和m.求sum(i^m)%2^32.(1<=i<=n) ...

  2. LRU缓存算法

    http://blog.csdn.net/beiyeqingteng/article/details/7010411 http://blog.csdn.net/wzy_1988/article/det ...

  3. public,protected,friendly,private的访问权限

    请说出作用域public,private,protected,以及不写时的区别 这四个作用域的可见范围如下表所示. 说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly. 作用域   ...

  4. bzoj2437

    会做jsoi那道game,这题就非常简单了吧 我们考虑空格的移动,显然,初始与空格位置距离为奇数的黑棋和距离为偶数的白棋并没有什么用, 空格不会移到那,我们直接把他们当作障碍,其他点我们当作可移动区域 ...

  5. bzoj4046

    分组赛的题……madan原题,考试想不出来真是SB得不行 首先,从大往小加边,每次加边如果成环必然弹出环上最大边 考虑询问[x,y],如果边权在[x,y]的边弹出了小于等于y的边j,说明j不在最小生成 ...

  6. ASP.NET MVC 学习7、为Model Class的字段添加验证属性(validation attribuate)

    Adding Validation to the Model ,在Model中添加数据验证 参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-star ...

  7. [.NET WebAPI系列03] WebAPI Controller 中标准CRUD方法

    [因] WebAPI的Controller中,一般都是下面四种方法: 对应于数据操作是我们通常所说的CRUD. C对应post,R对应Get,U对应Put,D对应Delete. 直接模仿VS 2012 ...

  8. 极光推送使用实例(二) Android客户端

    上一篇简单介绍了极光推送在Java服务端的实现,如果感兴趣的可以看一下极光推送使用实例(一)JAVA服务端.这篇文章介绍下极光推送在Android客户端的实现. JPush Android SDK 是 ...

  9. 《C++ Primer 4th》读书笔记 第10章-关联容器

    原创文章,转载请注明出处:http://www.cnblogs.com/DayByDay/p/3936464.html

  10. jdbc:oracle:thin:@192.168.3.98:1521:orcl(详解)

    整理自互联网 一. jdbc:oracle:thin:@192.168.3.98:1521:orcljdbc:表示采用jdbc方式连接数据库oracle:表示连接的是oracle数据库thin:表示连 ...