POJ_1703 并查集应用
通过这题基本完整理解了并查集的构建和使用。很轻巧的一种数据结构。
本题的方法值得注意:并没有直接构建两个帮派的集合,而是构建:
关系确认集合+若干单元素集(也即未确认帮派的初始状态)并辅助一个rel数组记录和父节点的关系(0相同,1不同)。
若关系确认,则将两个树合并到一棵树上;同时凭借rel数组判断是否和父亲属于同一帮派,进而判断两个元素是否属于同一帮派。
本题的思路很清楚,但难点在于如何合并集合 和 如何更新rel数组。
此处附上某大佬的解题报告,非常清晰(同时在更新rel的方法上并不唯一,代码中注释部分给出了第二种判定方式,本质是一样的)
大佬链接:https://www.cnblogs.com/zzy19961112/p/6043420.html
ac代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
//一言以蔽之,并查集是一种越查越快的数据结构
const int maxn=;
int t,n,m,a,b;
int p[maxn];
int rel[maxn];//为0表示与父一样,否则为不一样
int find(int x){
int temp=p[x];
if(x==p[x]){
return x;
}
p[x]=find(p[x]);//搜索优化 p[x]=根。使得下次查找时只需一次查找 (开始看的时候没有深刻理解这一句的作用)
//这里存在一个递归思维,也就是说,在给rel[x]赋值之前已经确保其父节点至根节点的值均已正确。
//int temp=p[x];//bug,不能写在这里,因为此时p[x]已经不再是父节点而是根节点
//rel[x]=(rel[temp]==rel[x])?0:1; //re[x]在未更新之前表示父子关系,更新后表示和根的关系。 (事实上此时x的父亲p[x]就等于根)
rel[x] = (rel[temp] + rel[x]) % ;
return p[x];
}
void unionset(int x,int y,int px,int py){
p[px]=py;
rel[px] = (rel[y] + - rel[x]) % ;
//rel[px]=(rel[x]==rel[y])?1:0;
}
int main(void){
cin>>t;
while(t--){
cin>>n>>m;
//初始化并查集;
for(int i=;i<=n;i++) {
p[i]=i;
rel[i]=;
}
while(m--){
char op;
int a,b;
scanf("\n%c %d %d",&op,&a,&b);
int pa=find(a),pb=find(b);
if(op=='A'){
if(pa!=pb){
printf("Not sure yet.\n");
continue;
} if(rel[a]==rel[b]){
printf("In the same gang.\n");
continue;
}
printf("In different gangs.\n");//太恶心了,一开始少了个句号,wa到怀疑人生;这个bug找得我心态快崩了。。。。 还是naive
continue;
}
if(op=='D'){
if(pa!=pb)unionset(a,b,pa,pb);
}
}
}
return ;
}
POJ_1703 并查集应用的更多相关文章
- POJ_1703 Find them, Catch them 【并查集】
一.题面 POJ1703 二.分析 需要将并查集与矢量法则相结合.par数组用以记录父节点,rank用以记录与父节点的关系.如题意,有两种关系,设定0是属于同一个帮派,1表示不属于同一个帮派. 运用并 ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- bzoj1854--并查集
这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- Codeforces 731C Socks 并查集
题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...
随机推荐
- debian卸载旧内核
debian卸载旧内核要先看看有哪些旧的内核,用命令: uname -a dpkg --get-selections |grep linux 如果你的内核是以kernel开头的就把上面的linux改成 ...
- 2017 Multi-University Training Contest - Team 1—HDU6035
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:一棵树有n个点,每个点有自己的颜色,任意两个不同的点可以组成一条路径.也就是说一共有n(n ...
- Arcengine 二次开发得到点shapefile的坐标
做二次开发的时候,想要得到Point shapfile的坐标和相应的属性,也就是Point 的(x,y)和某个属性,在网上查了一些资料,做总结如下 首先,你要确定自己要操作的图层,一般来说,得到当前操 ...
- 前端开发 - CSS - 下
CSS: 12.display 13.浮动效果 14.浮动特性 15.浮动产生的问题和解决方法 16.float京东导航栏 17.position 18.z-index 19.京东案例 12.disp ...
- ubuntu安装Jenkins指导
乌班图安装Jenkins指导 安装Java :apt install default-jre 参考:https://www.cnblogs.com/xionggeclub/p/7117004.html ...
- Python并行编程(八):with语法
1.基本概念 当有两个相关的操作需要在一部分代码块前后分别执行的时候,可以使用with语法自动完成.同时,使用with语法可以在特定的地方分配和释放资源,因此,with语法也叫作"上下文管理 ...
- HTTP和HTTPS的请求和响应
HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法.HTTPS(Hypertext Transfer Protocol ove ...
- android 知识收集
1.无论是 Activity.BroadcastReceiver还是Service,只要是有长时间处理的任务,就需要重新开一个线程来处理,为什么会这样? 因为他们都是运行在主线程中的. 2.在使用Br ...
- python的scikit-learn的主要模块和基本使用
在从事数据科学的人中,最常用的工具就是R和Python了,每个工具都有其利弊,但是Python在各方面都相对胜出一些,这是因为scikit-learn库实现了很多机器学习算法. 加载数据(Data L ...
- sails ORM组件 Waterline v0.10 英文文档
http://sailsdoc.swift.ren/ 这里有 sails中文文档 Introduction Installation Getting Started Models Data types ...