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 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...
随机推荐
- C#、devExpress 的 给bandedGrid加菜单功能 :复制、粘贴的例子(转)
C#.devExpress 的 给bandedGrid加菜单功能 :复制.粘贴的例子 CopyFromGrid PasteToGrid PasteNewRowsToGrid private void ...
- c++拷贝构造函数,深拷贝,浅拷贝,对象内存
https://blog.csdn.net/lwbeyond/article/details/6202256 防止默认拷贝发生 通过对对象复制的分析,我们发现对象的复制大多在进行“值传递”时发生,这里 ...
- java 多线程 day16 CountDownLatch 倒计时计数器
import java.util.concurrent.CountDownLatch;import java.util.concurrent.CyclicBarrier;import java.uti ...
- java 多线程 day12 读写锁
import java.util.Random;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent. ...
- 论MYSQL数据库数据错误的处理
1,备份 2,事务回滚 3,binlog日志回复 4,以上措施都没有,那就望洋兴叹吧
- 查看MySQL变量
类似于Oracle的参数文件,MySQL的选项文件(如my.cnf)用于配置MySQL服务器,但和Oracle叫法不一样,在MySQL里, 官方叫变量(Varialbes),但其实叫参数也是可以的,只 ...
- vue的项目结构
一. 准备工作 1. 初始化项目 vue init webpack itany cd itany cnpm install cnpm install less less-loa ...
- 草稿:SCADA全局底层框架架构
一:全局基于单文档MFC程序开发. 二:全局每个功能模块之间完全隔离, 模块之间的数据交流必须使用主板模板. 三:每个功能块全部都自己的线程,除了PLC功能块 其他都是窗口线程 四:各个功能命名的前缀 ...
- [Python] logging.logger
<1>. mylogger = logging.getLogger("abc") logging.debug()/logging.info()/logging.warn ...
- python全栈开发从入门到放弃之socket并发编程多进程
1.1 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程 ...