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 ...
随机推荐
- ubuntu 安装 docker
安装命令 sudo apt-get update sudo apt-get install docker.io 启动docker后台服务 sudo service docker start 1.删除镜 ...
- 【虚拟机】:"该虚拟机似乎正在使用中。 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。否则,请按“取消(C)”按钮以防损坏。"
1.可能是由于上次使用虚拟机,没有正常关闭出现了这种情况,于是把问题复制粘贴搜了一下. 2.出现了如下可行的解决方法:把后缀名为.vmdk.lck的都删除掉. 3.然后再打开虚拟机就可以了.
- Bootstrap 网页实例
代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <met ...
- 【Flutter学习】之DateTime日期转换
概述: 表示一个时间点 通过构造函数或解析格式化的字符串创建DateTime对象,并且符合ISO 8601标准的子集,小时是24小时制,范围在0-23之间 DateTime对象创建之后,将是固定不变的 ...
- zoj 2112 单点修改的主席树(树状数组套主席树)
题目大意: 区间第k大问题+单点修改 基本思路: 这个题有用整体二分,cdq分治,还有主席树+平衡树的,还有就是主席树+树状数组. 我采用的是b站电子科大大佬的主席树写法,尤其喜欢他的离散化方法,所以 ...
- Win7 VS2012智能提示显示英文的处理办法
其原因为.net的语言包没安装成功, 解决方法为 替换自己英文显示的,把C:\Windows\Microsoft.NET\Framework\v2.0.50727\zh-CN 目录的文件,替换到相应的 ...
- boost库:多线程
1.线程管理 最重要的一个类是boost::thread,是在boost/thread.hpp里定义的,用来创建一个新线程. #include <boost/thread.hpp> #in ...
- 【InnoDB】插入缓存,两次写,自适应hash索引
InnoDB存储引擎的关键特性包括插入缓冲.两次写(double write).自适应哈希索引(adaptive hash index).这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性. ...
- MaxCompute问答整理之10月
本文是基于本人对MaxCompute产品的学习进度,再结合开发者社区里面的一些问题,进而整理成文.希望对大家有所帮助. 问题一.DataStudio中是否可以通过shell节点调取MaxCompute ...
- 【C#、阿里云、Tomcat、XP系统】c#下使用.NET4.0中HttpWebRequest访问Tomcat中HTTPS项目时,在XP系统中超时
情景: 1.使用Java开发的Web项目,部署在服务器Tomcat中 2.项目使用HTTPS,使用阿里云的PFX证书 阿里云推荐Tomcat配置如下 <Connector port=" ...