隐藏页面特效

CF506D Mr. Kitayuta's Colorful Graph

好久没更新这个单题系列了,主要是最近没啥CF比赛空闲时间又少,今天忙里偷闲写了两个题

这个题就比较典了,两点是否连通一般都是想到并查集维护,现在的问题是要对每种颜色的边把贡献算清楚

很容易想到枚举所有颜色的边,每次求出所有连通分量后遍历一遍询问统计答案,这样正确性显然但复杂度是O(m×(n+q))

冷静思考一下会发现其实很多时候连通分量的大小和数量都很少,完全不需要我们暴力遍历所有询问,我们可以直接平方暴力枚举一个连通分量内的所有点对,然后把它对应的询问的答案更新即可

然后结合两种算法就很容易得到一个根号分治的做法,我们设阈值S=m

对于某种颜色的边,如果其边数>S就直接跑前面的算法,否则记录下所有用到的点,遍历每个联通块即可

总复杂度O(mm×(α(n)+logn))

#include<cstdio> #include<iostream> #include<utility> #include<vector> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> #include<set> #include<map> #include<set> #include<array> #include<random> #include<bitset> #include<ctime> #include<limits.h> #include<assert.h> #include<unordered_set> #include<unordered_map> #define RI register int #define CI const int& #define mp make_pair #define fi first #define se second #define Tp template <typename T> using namespace std; typedef long long LL; typedef long double LDB; typedef unsigned long long u64; typedef __int128 i128; typedef pair <int,int> pi; typedef vector <int> VI; typedef array <int,3> tri; const int N=100005; int n,m,a,b,c,q,x[N],y[N],ans[N],fa[N]; vector <pi> col[N]; vector <int> num[N]; map <pi,vector <int>> qid; inline int getfa(CI x) { return fa[x]!=x?fa[x]=getfa(fa[x]):x; } int main() { //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); RI i,j,k; for (scanf("%d%d",&n,&m),i=1;i<=m;++i) scanf("%d%d%d",&a,&b,&c),col[c].push_back(pi(a,b)); for (i=1;i<=n;++i) fa[i]=i; for (scanf("%d",&q),i=1;i<=q;++i) { scanf("%d%d",&x[i],&y[i]); if (x[i]>y[i]) swap(x[i],y[i]); qid[pi(x[i],y[i])].push_back(i); } int S=(int)sqrt(m); for (i=1;i<=m;++i) { if (col[i].size()<=S) { vector <int> pnt; for (auto [a,b]:col[i]) pnt.push_back(a),pnt.push_back(b),fa[getfa(a)]=getfa(b); sort(pnt.begin(),pnt.end()); pnt.erase(unique(pnt.begin(),pnt.end()),pnt.end()); for (auto x:pnt) num[getfa(x)].push_back(x); for (auto x:pnt) if (getfa(x)==x) { for (j=0;j<num[x].size();++j) for (k=j+1;k<num[x].size();++k) { a=num[x][j]; b=num[x][k]; if (a>b) swap(a,b); if (qid.count(pi(a,b))) for (auto it:qid[pi(a,b)]) ++ans[it]; } } for (auto x:pnt) num[x].clear(),fa[x]=x; } else { for (auto [a,b]:col[i]) fa[getfa(a)]=getfa(b); for (j=1;j<=q;++j) ans[j]+=getfa(x[j])==getfa(y[j]); for (j=1;j<=n;++j) fa[j]=j; } } for (i=1;i<=q;++i) printf("%d\n",ans[i]); return 0; }

__EOF__

本文作者hl666
本文链接https://www.cnblogs.com/cjjsb/p/17747297.html
关于博主:复活的ACM新生,目前爱好仅剩Gal/HBR/雀魂/单机/OSU
版权声明:转载请注明出处
声援博主:欢迎加QQ:2649020702来DD我
posted @   空気力学の詩  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
历史上的今天:
2022-10-07 Codeforces Global Round 22(持续更新)
2020-10-07 Luogu P6105 [Ynoi2010]y-fast trie
2020-10-07 Luogu P3248 [HNOI2016]树
2020-10-07 BZOJ #4282. 慎二的随机数列
2018-10-07 bitset常用用法&&简单题分析
点击右上角即可分享
微信分享提示