题目链接:

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. python selenium3 模拟点击+拖动+保存验证码 测试对象 58同城验证码

    #!/usr/bin/python # -*- coding: UTF-8 -*- # @Time : 2019/12/5 17:30 # @Author : shenghao/10347899@qq ...

  2. 用表格制作商品购买页面--(table)

    实现效果如图: 首先来看布局,头部图片,内容从左到右分为四个部分   勾选+商品图片+商品名/买家+价格, 所以需要将头部用<td>包括起来,并且设置<td colspan=&quo ...

  3. windows 日志清理和设置

    Windows日志路径 c:/windows/system32/winevt/logs 这里的日志文件可以ctrl+a 选中后使用shift+delete进行删除,删不掉的可以点击跳过.   在“管理 ...

  4. Impala 中invalidate metadata和refresh

    首先了解一下:Impala如何融入Hadoop生态系统 Impala使用了Hadoop生态系统中许多熟悉的组件.Impala可以作为消费者和生产者与其他Hadoop组件交换数据,因此它可以以灵活的方式 ...

  5. 【Git】一、安装、配置和仓库创建

    之前一直使用图形界面的git,只会一些最常用的操作,并没有说深入学习git的全部功能 开发这么久了,觉得是时候学习一下指令操作,更快捷也更bigger ------------------------ ...

  6. DB2 alter 新增/删除/修改列

    SQL语句 增加列.修改列.删除列 1 添加字段 语法 : alter table 表名称 add 字段名称 类型 demo: alter table tableName add columnName ...

  7. Django_01_创建图书管理项目

    在django中,项目的组织结构为一个项目包含多个应用,一个应用对应一个业务模块 示例:创建项目的名称为test1,完成“图书-英雄”信息的维护,创建应用名称为booktest 创建项目:首先进入到虚 ...

  8. DA_03_linux网络配置及其远程连接

    一: 修改Linux的基本配置 直接运行:setup,根据提示修改 1.修改主机名:vi /etc/sysconfig/network NETWORKING=yes HOSTNAME=shizhan1 ...

  9. 共享手机网络给电脑(USB连接)

    华为手机步骤: 设置-->搜索-->hdb-->允许HiSuite通过HDB连接设置 设置-->无线和网络-->移动网络共享-->USB共享网络

  10. Event Binding in Angular

    https://www.pluralsight.com/guides/angular-event-binding Introduction In this guide, we will explore ...