CF506D Mr. Kitayuta's Colorful Graph

题目

CF506D Mr. Kitayuta's Colorful Graph

给出一个无向图,每条边有颜色,每次询问两点间可以由多少种不同颜色的路径相互到达(要求路径上全是那一种颜色)。

分析

直接开一个 \(\text{unorderedmap}\) ,维护每一个点对应颜色的并查集父亲。

然后考虑记忆化答案,每次直接询问就是直接查找和这个点有连边的所有颜色,查看其是否和另外一个点在这个颜色上连通。

时间复杂度是 \(O(n\alpha(n)\sqrt{n})\) 的。

分析:

如果一个点连出去的颜色超过了 \(\sqrt{n}\) 种,那么这样的点不超过 \(\sqrt{n}\) 个,因为我们记忆化过,所以这样的总状态只有 \(n\sqrt{n}\)

剩下的是没有超过 $ \sqrt{n}$ 的,直接暴力询问即可。

时间复杂度 \(O(n\alpha(n)\sqrt{n})\)

注意!\(\text{unorderedmap}\) 的下标访问非常慢!要使用 \(count\) 函数!

代码

#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T &x){
	x=0;bool f=false;char ch=getchar();
	while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
	while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
	x=f?-x:x;
	return ;
}
template<typename T>
inline void write(T x){
	if(x<0) x=-x,putchar('-');
	if(x>9) write(x/10);
	putchar(x%10^48);
	return ;
}
#define PII pair<int,int>
#define fi first
const int N=1e5+5,M=2e5+5,MOD=1e9+7;
unordered_map<int,int>fa[N],Ans[N];
int n,m,q;
int Getfa(int x,int col){return fa[x][col]==x?x:(fa[x][col]=Getfa(fa[x][col],col));}
inline void Merge(int x,int y,int col){
	if(!fa[x].count(col)) fa[x][col]=x;
	if(!fa[y].count(col)) fa[y][col]=y;
	x=Getfa(x,col),y=Getfa(y,col);
	if(x==y) return ;
	fa[x][col]=y;
	return;
}
signed main(){
	read(n),read(m);
	for(register int i=1,u,v,w;i<=m;i++) read(u),read(v),read(w),Merge(u,v,w);
	read(q);
	while(q--){
		int u,v,res=0;read(u),read(v);
		if(fa[u].size()>fa[v].size()) swap(u,v);
		if(Ans[u].count(v)){write(Ans[u][v]);putchar('\n');continue;}
		for(PII t:fa[u]) res+=(fa[v].count(t.fi)&&Getfa(u,t.fi)==Getfa(v,t.fi));
		write(Ans[u][v]=res);putchar('\n');
	}
	return 0;
}



扩展

貌似有 \(bitset\) 高妙做法:一念之间、、 的博客

posted @ 2021-09-14 10:12  __Anchor  阅读(38)  评论(0编辑  收藏  举报