Mr. Kitayuta's Colorful Graph

算法:根号分治。

题目大意先说一下:给一个 \(n\) 点 \(m\) 边的无向图,边有颜色。\(q\) 组询问,每次给出 \(u,v\),求有多少种颜色 \(c\),使得存在一条 \(u\) 到 \(v\) 的路径,这个路径中每条边的颜色都为 \(c\)。

数据范围:\(2\le n\le 10^5,1\le c\le m,q\le 10^5\)。

先考虑一个朴素的暴力,暴力对每个颜色加边,用并查集判连通性,暴力扫过每个询问,如果在一个颜色上这两个点是连通的,答案加 \(1\)。

发现这种做法在颜色非常多的时候要扫过每个颜色和每个询问的时间复杂度非常高,难以接受,所以要考虑优化。

我们怎么优化?上文提及了在颜色非常多的时候复杂度会爆炸,那么他有什么优势?当然是在颜色少的时候跑得很快,那么我们采取他的优势,想一想颜色多的时候的优秀的写法。

这里可以停顿 \(1\) 分钟,自己想一下。

我们可以发现,既然颜色多,边的数量不会太多,那么就证明每个颜色的边连接的点不会太多,所以我们可以暴力枚举这样的颜色的边连接的点,判断是否连通,如果连通就答案加 \(1\)。

但是会出现一个问题,如果这个点对不在询问里怎么办?这其实是无关紧要的,因为询问的我们会处理到,没有询问的随便加也不会影响。

所以我们记颜色 \(c\) 的边数为 \(cnt_c\),以 \(\sqrt m\) 为分界线,判断使用哪种暴力。

由于这道题的代码作者认为并不好写,所以下面放一下代码。

#include<bits/stdc++.h>
#define int long long
#define N 100005
#define pii pair<int,int>
#define x first
#define y second
using namespace std;
int n,m,q,cnt[N];
int p[N];
vector<pii>e[N],qry,rqry,f[N];
map<int,bool>col;
map<pii,int>res;
int find(int x){
if(p[x]!=x)p[x]=find(p[x]);
return p[x];
}
void force1(){
for(int i=1;i<=n;i++){
p[i]=i;
}
for(auto eu:col){
int c=eu.x;
if(cnt[c]<sqrt(m))continue;
for(auto edge:e[c]){
int a=edge.x,b=edge.y;
int fa=find(a),fb=find(b);
if(fa!=fb){
p[fa]=fb;
}
}
map<pii,bool>st;
for(auto eu:qry){
int a=eu.x,b=eu.y;
if(st[{a,b}])continue;
int fa=find(a),fb=find(b);
if(fa==fb)res[{a,b}]++;
st[{a,b}]=1;
}
for(auto color:e[c]){
int a=color.x,b=color.y;
p[a]=a;p[b]=b;
}
}
}
void force2(){
for(int i=1;i<=n;i++){
p[i]=i;
}
for(auto eu:col){
int c=eu.x;
if(cnt[c]>=sqrt(m))continue;
vector<int>ind;
map<int,bool>state;
for(auto edge:e[c]){
int a=edge.x,b=edge.y;
if(!state[a]){
state[a]=1;
ind.push_back(a);
}
if(!state[b]){
state[b]=1;
ind.push_back(b);
}
int fa=find(a),fb=find(b);
if(fa!=fb){
p[fa]=fb;
}
}
for(int i=0;i<ind.size();i++){
for(int j=i+1;j<ind.size();j++){
int a=ind[i],b=ind[j];
int c=min(a,b),d=max(a,b);
int fa=find(c),fb=find(d);
if(fa==fb){
res[{c,d}]++;
}
}
}
for(auto color:e[c]){
int a=color.x,b=color.y;
p[a]=a;p[b]=b;
}
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
if(a>b)swap(a,b);
cnt[c]++;
col[c]=1;
e[c].push_back({a,b});
}
cin>>q;
for(int i=1;i<=q;i++){
int a,b;
cin>>a>>b;
if(a>b)swap(a,b);
qry.push_back({a,b});
rqry.push_back({a,b});
}
sort(qry.begin(),qry.end());
qry.erase(unique(qry.begin(),qry.end()),qry.end());
force1();
force2();
for(auto eu:rqry){
int a=eu.x,b=eu.y;
cout<<res[{a,b}]<<'\n';
}
return 0;
}

CF506D题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. CNN -- Simple Residual Network

    Smiling & Weeping ---- 我爱你,从这里一直到月亮,再绕回来 说明: 1.要解决的问题:梯度消失 2. 跳连接,H(x) = F(x)+x,张量维度必须一致,加完后再激活. ...

  2. 字符串— trim()、trimStart() 和 trimEnd()

    在今天的教程中,我们将一起来学习JavaScript 字符串trim().trimStart() 和 trimEnd(). 01.trim() 学习如何使用 JavaScript  trim()方法从 ...

  3. python 发起PUT请求,报"Method not Allowed" 和 取返回的报文的内容

    发起请求的时候,默认使用的POST请求方式,导致发起请求,返回[405 Method not Allowed ],检查此更新接口的请求方式为PUT,更改请求方式为PUT PUT接口返回的内容,不能通过 ...

  4. MYSQL-check管理

    mysql这个东西对于管理员并不友好,看起来还没有成品.就拿亲儿子workbeanch来说吧,功能也不是很齐全,速度也一般般,否则sqlyog之类的早没有什么活路了. 社区版的支持非常薄弱(商业版不太 ...

  5. ServiceMesh、SideCar和Istio

    Service Mesh简介 Service Mesh直译过来就是服务网格,而他的架构就是一个个微服务组成的网络. Sidecar简介 Service Mesh中的节点就是Sidecar节点. sid ...

  6. mysqldump备份时保持数据一致性分析--master-data=2 --single-transaction

    对MySQL数据进行备份,常见的方式如以下三种,可能有很多人对备份时数据一致性并不清楚 1.直接拷贝整个数据目录下的所有文件到新的机器.优点是简单.快速,只需要拷贝:缺点也很明显,在整个备份过程中新机 ...

  7. Apline部署K3s的Agent

    之前我们在Ubuntu上部署了K3s的Server节点(传送门),这次我们加入两台K3s的Agent节点搭建一个K3s的3节点工作环境. 需要准备好网络环境,确保三台VM之间是可以ping通的,设置好 ...

  8. Blazor Server App Cannot find the fallback endpoint specified by route values

    github官方issues中提到的解决方案,CreateBuilder时指定项目绝对路径可以解决. 1 // 指定项目路径,也可以用Assembly.GetCallingAssembly获取 2 c ...

  9. Vite5+Electron聊天室|electron31跨平台仿微信EXE客户端|vue3聊天程序

    基于electron31+vite5+pinia2跨端仿微信Exe聊天应用ViteElectronChat. electron31-vite5-chat原创研发vite5+electron31+pin ...

  10. C# 语言笔记

    1. C# 初识 因为先前已经学过 C++ 了,所以在C# 的学习中,大多只记录和 C++ 不同的点,在学习的过程中,感谢刘铁猛老师的教程,您是我C# 入门的领路人. 1.1 使用 .net cli ...