UVALive 6910 Cutting Tree(离线逆序并查集)
【题目】:(地址:)
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(离线逆序并查集)的更多相关文章
- UVALive - 6910 (离线逆序并查集)
题意:给处编号从1~n这n个节点的父节点,得到含有若干棵树的森林:然后再给出k个操作,分两种'C x'是将节点x与其父节点所连接的支剪短:'Q a b'是询问a和b是否在同一棵树中. 题解:一开始拿到 ...
- UVALive 6910 Cutting Tree(并查集应用)
总体来说,这个题给的时间比较长,样例也是比较弱的,别的方法也能做出来. 我第一次使用的是不合并路径的并查集,几乎是一种暴力,花了600多MS,感觉还是不太好的,发现AC的人很多都在300MS之内的过得 ...
- UVALive 6910 Cutting Tree 并查集
Cutting Tree 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8& ...
- ZOJ-3261 Connections in Galaxy War---离线操作+逆序并查集
题目链接: https://cn.vjudge.net/problem/ZOJ-3261 题目大意: 给你一些点,还有一些边,每个点上都有一个权值,然后有一些询问,分为两种,query a 询问与a直 ...
- Connections in Galaxy War ZOJ - 3261 离线操作+逆序并查集 并查集删边
#include<iostream> #include<cstring> #include<stdio.h> #include<map> #includ ...
- hdu 5441 Travel 离线带权并查集
Travel Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5441 De ...
- hdu 5441 travel 离线+带权并查集
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Descript ...
- LCA(最近公共祖先)离线算法Tarjan+并查集
本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...
- 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 ...
随机推荐
- Xcode学习
http://www.cnblogs.com/ygm900/p/3488881.html
- sublime-text3插件安装
sublime-text3和sublime-text2一样安装插件前都需要先安装,Package control ,然而安装Package control的代码和sublime-text2又不相同.如 ...
- Struts框架搭建时所遇到的问题
问题一:Unable to load configuration. - bean - jar:file:/D:/Tomcat%206.0/webapps/bar/WEB-INF 原 因:可 ...
- POJ 1966 Cable TV Network (无向图点连通度)
[题意]给出一个由n个点,m条边组成的无向图.求最少去掉多少点才能使得图中存在两点,它们之间不连通. [思路]回想一下s->t的最小点割,就是去掉多少个点能使得s.t不连通.那么求点连通度就枚举 ...
- Linux likely unlikely
/************************************************************************* * Linux likely unlikely * ...
- memcache的最佳实践方案。
基本问题 1.memcached的基本设置 1)启动Memcache的服务器端 # /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 ...
- ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片
这里请注意,在编译ffmpeg时,不要使用--disable-devices选项. 使用 --enable-encoder=rawvideo --enable-decoder=rawvideo 启用r ...
- Mac终端编译运行C++
1.在编辑器中写好C++代码 2.打开终端打开文件对应的地址 3.用g++命令来编译.cpp文件 4.用./文件名来运行 观察文件的目录可发现 g++ 源文件名 编译源文件,产生a.out ./文件名 ...
- 【DFS/BFS】NYOJ-58-最少步数(迷宫最短路径问题)
[题目链接:NYOJ-58] 经典的搜索问题,想必这题用广搜的会比较多,所以我首先使的也是广搜,但其实深搜同样也是可以的. 不考虑剪枝的话,两种方法实践消耗相同,但是深搜相比广搜内存低一点. 我想,因 ...
- K2 blackpearl 流程开发(二)
转:http://blog.csdn.net/gxiangzi/article/details/8444590 本来想一篇文章把流程开发介绍完的,后来发现实在是太多了,只好分成两部分了.上一篇很简单的 ...