题目链接:

https://codeforces.com/contest/1166/problem/F

题意:

给出节点数为$n$,边数为$m$的图,保证每个点对都是互连的

定义彩虹路:这条路经过$k$个节点,对于$x(x\%2=0)$节点,的左右两条边颜色相同

现在有$q$次操作

第一种操作是添加一条边

第二种操作是回答是否能经过彩虹边从$a$节点到达$b$节点

数据范围:

$2 \le n \le 10^5$
$1 \le m,q \le 10^5$

分析:

我们可以考虑用并查集把那些可以互相到达(经过边数为偶数的彩虹路)的点对用并查集连接起来

当$a-b-c$的边的颜色相同时,我们把a和c节点用并查集连接起来,代表$a$和$c$互连

对于节点a,每个颜色的边只需要保存一条,这样可以快速合并节点

这样,两个点是否能到达,只需要判断他们的并查集根是不是相同

但是还有一种情况,$x$节点到$y$节点经过的边数为奇数,这样最后一条边的颜色就不重要了

我们可以给每个并查集添加一个集合,集合里面的点直接连接某个并查集的点

连接两个并查集用到了启发式合并(整个合并操作复杂度为$O(nlgn)$)

ac代码:

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pa pair<int,int>
using namespace std;
const int maxn=1e5+10;
const int maxm=5e6+10;
const ll mod=1e9+7;
map<int,int>ma[maxn];//对于节点a,每个颜色的边只需要保存一条
set<int>se[maxn];
int n,m,c,q,boss[maxn];
void inti()
{
for(int i=1;i<=n;i++)
boss[i]=i;
}
int fin(int x)
{
if(boss[x]==x)return x;
return boss[x]=fin(boss[x]);
}
void uni(int a,int b)
{
int v1=fin(a),v2=fin(b);
if(v1==v2)return;
if(se[v1].size()>se[v2].size())swap(v1,v2);//启发式合并关键
boss[v1]=v2;
for(auto i :se[v1])se[v2].insert(i);
se[v1].clear();
}
void add_edge()
{
int a,b,v;
scanf("%d %d %d",&a,&b,&v);
if(ma[a].count(v))
uni(ma[a][v],b);
else
ma[a][v]=b;
if(ma[b].count(v))
uni(ma[b][v],a);
else
ma[b][v]=a;
se[fin(a)].insert(b);
se[fin(b)].insert(a);
}
int main()
{
scanf("%d %d %d %d",&n,&m,&c,&q);
inti();
for(int i=1; i<=m; i++)
add_edge();
while(q--)
{
getchar();
if(getchar()=='?')
{
int fla=0,a,b;
scanf("%d %d",&a,&b);
int v=fin(a);
if(v==fin(b)||se[v].find(b)!=se[v].end())//同一个集合,或者不同集合,但是再走一条边能到
printf("Yes\n");
else
printf("No\n");
}
else
{
add_edge();
}
}
return 0;
}

  

codeforces#1166F. Vicky's Delivery (Service并查集+启发式合并)的更多相关文章

  1. BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并

    题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...

  2. BZOJ 4668: 冷战 并查集启发式合并/LCT

    挺好想的,最简单的方法是并查集启发式合并,加暴力跳父亲. 然而,这个代码量比较小,比较好写,所以我写了 LCT,更具挑战性. #include <cstdio> #include < ...

  3. [HDU 3712] Fiolki (带边权并查集+启发式合并)

    [HDU 3712] Fiolki (带边权并查集+启发式合并) 题面 化学家吉丽想要配置一种神奇的药水来拯救世界. 吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[ ...

  4. [BZOJ 4668]冷战(带边权并查集+启发式合并)

    [BZOJ 4668]冷战(并查集+启发式合并) 题面 一开始有n个点,动态加边,同时查询u,v最早什么时候联通.强制在线 分析 用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与 ...

  5. Codeforces 1166F 并查集 启发式合并

    题意:给你一张无向图,无向图中每条边有颜色.有两种操作,一种是询问从x到y是否有双彩虹路,一种是在x到y之间添加一条颜色为z的边.双彩虹路是指:如果给这条路径的点编号,那么第i个点和第i - 1个点相 ...

  6. BZOJ 3673: 可持久化并查集(可持久化并查集+启发式合并)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3673 题意: 思路: 可持久化数组可以用可持久化线段树来实现,并查集的查询操作和原来的一般并查集操作 ...

  7. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  8. 【AGC014E】Blue and Red Tree 并查集 启发式合并

    题目描述 有一棵\(n\)个点的树,最开始所有边都是蓝边.每次你可以选择一条全是蓝边的路径,删掉其中一条,再把这两个端点之间连一条红边.再给你一棵树,这棵树的所有边都是红边,问你最终能不能把原来的树变 ...

  9. 2018.08.21 bzoj4668: 冷战(并查集+启发式合并)

    传送门 可以发现需要维护连通性和两点连通时间. 前者显然是并查集的常规操作,关键就在于如何维护两点的连通时间. 然后会想到这个时候不能用路径压缩了,因为它会破坏原本树形集合的结构,因此可以启发式按si ...

随机推荐

  1. 怎样查看Nginx版本号

    方法一: 使用 nginx -v nginx -v 方法二: 使用 nginx -V nginx -V 注意: nginx -V 显示的是: 版本号 / 编译器版本 / 配置参数

  2. JAVA中ArrayList重写比较方法

    ArrayList的sort方法重写: 当ArrayList中存放的为含有多个成员变量的数据类型时,在进行sort排序时要重写比较方法,一般都写在这个数据类型类的内部如: package 算法竞赛入门 ...

  3. windows连接远程服务器报错'SSH' 不是内部或外部命令,也不是可运行的程序 或批处理文件 解决方案

    网上在windows下连接远程服务器的步骤如下: 1.打开cmd命令行窗口 2.输入cd ~/.ssh,进入c盘下的.ssh文件 3.输入“ssh root@远程服务器的ip地址”连接远程服务器, b ...

  4. NodeJS express框架的使用

    首先,可以通过npm或者淘宝镜像cnpm全局安装epress框架,这里不具体说了 npm install -g expressnpm install -g express-generator 新建一个 ...

  5. bootsctrap4 datepicker时间选择插件

    现在网上基本都是v3的时间选择插件,花了点时间改了找了个v4能用的 bootstrap-datepicker <!DOCTYPE html> <html> <head&g ...

  6. Delphi 10.3.3最新消息

    有朋友说,已经开始内测,预计10月末发版,按最新的路线图,此版本支持iOS 13及Android 64位. 2019-11-18,今天,下载及注册机都来了,快下载安装,试用吧. 需要的话加入QQ群20 ...

  7. 12个提高Java程序员工作效率的工具

    Java开发者常常都会想办法如何更快地编写Java代码,让开发过程变得更加轻松,更加高效.目前,市面上涌现出越来越多的高效编程工具.团长总结了几个常用的工具,其中包含了大多数开发人员已经使用.正在使用 ...

  8. pycharm中代码窗口如何分成左右或者上下双栏

    操作步骤如下: 其中window->edit_tabs->Split Vertically 是分成左右双栏:选择Split Horizontally 是分成上下双栏

  9. WebLogic 12c Linux 命令行 静默安装

    CentOS 6.3安装配置Weblogic 10  http://www.linuxidc.com/Linux/2014-02/96918.htm Oracle WebLogic 11g 安装部署文 ...

  10. 软件测试能满足测试的sql

    作为一个软件测试工程师,我们在测试过程中往往需要对数据库数据进行操作,但是我们的操作大多以查询居多,有时会涉及到新增,修改,删除等操作,所以我们其实并不需要对数据库的操作有特别深入的了解,以下是我在工 ...