Codeforces 1166F 并查集 启发式合并
题意:给你一张无向图,无向图中每条边有颜色。有两种操作,一种是询问从x到y是否有双彩虹路,一种是在x到y之间添加一条颜色为z的边。双彩虹路是指:如果给这条路径的点编号,那么第i个点和第i - 1个点相连的边与第i个点和第i + 1个点相连的边颜色一样,其中i是偶数。
思路:这个问题相当于初了最后一步没有限制以外(最后一步只走一条边),每一步都要走颜色相同的两条边。我们先不考虑最后一步的问题,只考虑每一步都要走颜色相同的两条边,那么我们只需要扫描每一个点的出边,如果有两条边颜色相同,就在一张新图上把这两条边除这个点以外的端点相连,这样询问就变成了判断两个点是否在一个连通块中。因为只是判断是否在同一连通块中,我们不需要建图,用并查集就可以了。现在需要考虑最后一步的问题,我们可以用一个set维护与这个节点直接相邻的点,这样对于询问x, y,如果y在连通块x的相邻节点中,也可以。对于加边的操作,相当于并查集的合并,但是同时需要合并的还有set, 我们合并的时候需要判断一下两个集合的大小,把小的插入大的里面,这样可以保证每次集合合并复杂度是O(logn * logn)的。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
set<int> s[maxn];
set<int>::iterator it1;
set<pair<int, int> > edge[maxn];
set<pair<int, int> >::iterator it;
int f[maxn];
int get(int x) {
if(x == f[x]) return x;
return f[x] = get(f[x]);
}
void merge(int x, int y) {
int x1 = get(x), y1 = get(y);
if(x1 == y1) return;
if(s[x1].size() < s[y1].size()) swap(x1, y1);
for (it1 = s[y1].begin(); it1 != s[y1].end(); it1++) {
s[x1].insert(*it1);
}
s[y1].clear();
f[y1] = x1;
}
void add(int x, int y, int z) {
s[get(x)].insert(y);
it = edge[x].lower_bound(make_pair(z, -1));
if(it == edge[x].end() || it -> first != z) {
edge[x].insert(make_pair(z, y));
} else {
merge(it -> second, y);
}
}
int main() {
int x, y, z, n, m, c, T;
char op[5];
scanf("%d%d%d%d", &n, &m, &c, &T);
for (int i = 1; i <= n; i++) f[i] = i;
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &x, &y, &z);
add(x, y, z);
add(y, x, z);
}
while(T--) {
scanf("%s", op + 1);
if(op[1] == '+') {
scanf("%d%d%d", &x, &y, &z);
add(x, y, z);
add(y, x, z);
} else {
scanf("%d%d", &x, &y);
if(get(x) == get(y)) {
printf("Yes\n");
} else if(s[get(x)].find(y) != s[get(x)].end()) {
printf("Yes\n");
} else {
printf("No\n");
}
}
}
}
Codeforces 1166F 并查集 启发式合并的更多相关文章
- BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...
- BZOJ 4668: 冷战 并查集启发式合并/LCT
挺好想的,最简单的方法是并查集启发式合并,加暴力跳父亲. 然而,这个代码量比较小,比较好写,所以我写了 LCT,更具挑战性. #include <cstdio> #include < ...
- [HDU 3712] Fiolki (带边权并查集+启发式合并)
[HDU 3712] Fiolki (带边权并查集+启发式合并) 题面 化学家吉丽想要配置一种神奇的药水来拯救世界. 吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[ ...
- [BZOJ 4668]冷战(带边权并查集+启发式合并)
[BZOJ 4668]冷战(并查集+启发式合并) 题面 一开始有n个点,动态加边,同时查询u,v最早什么时候联通.强制在线 分析 用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与 ...
- BZOJ 3673: 可持久化并查集(可持久化并查集+启发式合并)
http://www.lydsy.com/JudgeOnline/problem.php?id=3673 题意: 思路: 可持久化数组可以用可持久化线段树来实现,并查集的查询操作和原来的一般并查集操作 ...
- codeforces#1166F. Vicky's Delivery (Service并查集+启发式合并)
题目链接: https://codeforces.com/contest/1166/problem/F 题意: 给出节点数为$n$,边数为$m$的图,保证每个点对都是互连的 定义彩虹路:这条路经过$k ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 2018.08.21 bzoj4668: 冷战(并查集+启发式合并)
传送门 可以发现需要维护连通性和两点连通时间. 前者显然是并查集的常规操作,关键就在于如何维护两点的连通时间. 然后会想到这个时候不能用路径压缩了,因为它会破坏原本树形集合的结构,因此可以启发式按si ...
- BZOJ4602: [Sdoi2016]齿轮(并查集 启发式合并)
题意 题目链接 Sol 和cc的一道题很像啊 对于初始的\(N\)个点,每加一条限制实际上就是合并了两个联通块. 那么我们预处理出\(val[i]\)表示的是\(i\)节点所在的联通块根节点转了\(1 ...
随机推荐
- 阿里云Linux(Centos7)下搭建SVN服务器
1,使用yum安装SVN yum -y install subversion 安装完成之后,验证安装结果 svn help 2,新建仓库目录 在/usr/soft目录下面创建一个svn目录,用来作为s ...
- 第8篇NFS PersistentVolume
一.部署nfs服务端: k8s-master 节点上搭建了 NFS 服务器,也可以在部署节点搭建,原理一样 (1)安装nfs服务: yum install -y nfs-utils rpcbind v ...
- JavaSE---Runtime类
1.概述 1.1 Runtime类 代表 java程序运行时环境: 1.2 Runtime类 提供的类方法: getRuntime():获取Runtime实例: gc():通知垃圾回收器回收资源: ...
- Linux进程基本原理
主题进程介绍 一进程相关概念 内核的功用:进程管理.文件系统.网络功能.内存管理.驱动程序.安全功能等 在操作系统上会运行多个应用程序,应用程序分配多大的内存都由内核实现 程序文件 程序和进程的关系 ...
- mysql查询诊断分析工具
Query Profiler是MYSQL自带的一种query诊断分析工具,通过它可以分析出一条SQL语句的性能瓶颈在什么地方.通常我们是使用的explain,以及slow query log都无法做到 ...
- 6.zabbix微信告警3.2
原文地址: https://blog.cactifans.com/2016/01/27/zabbix%E5%BE%AE%E4%BF%A1%E5%91%8A%E8%AD%A6/ pdf : 链接: ht ...
- (转)Android OpenGL ES(一)
转:http://wiki.jikexueyuan.com/project/opengl-es-guide/pipeline.html OpenGL ES 主要用来开发 3D 图形应用的.OpenGL ...
- How do I force my .NET application to run as administrator?
How do I force my .NET application to run as administrator? You'll want to modify the manifest that ...
- Redis Cluster 设置密码
两种方式 1.修改配置文件 在每个节点的配置文件里面增加密码选项,一定要加上 masterauth,不然 Redirected 的时候会失败. masterauth redispassword req ...
- js对div取值与赋值
js对div取值与赋值 因为JavaScript运行时,id="test1" 的那个div元素可能还没解析和加载,js加载是有顺序的.只需把 js 整个搬到 后面即可. 还有一个特 ...