首页 > 其他分享 >CF506D题解

CF506D题解

时间:2024-07-11 09:54:07浏览次数:11  
标签:颜色 int 题解 back eu CF506D qry find

Mr. Kitayuta's Colorful Graph

算法:根号分治。

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

先考虑一个朴素的暴力,暴力对每个颜色加边,用并查集判连通性,暴力扫过每个询问,如果在一个颜色上这两个点是连通的,答案加 \(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;
}

标签:颜色,int,题解,back,eu,CF506D,qry,find
From: https://www.cnblogs.com/zxh923aoao/p/18295429

相关文章

  • UVA12683 Odd and Even Zeroes 题解
    题目简述定义\(\operatorname{count}(num)\)表示\(num\)末尾\(0\)的个数。给出\(n\)(\(n\leq10^{18}\)),求\(\sum\limits_{i=0}^{n}[2\mid\operatorname{count}(i!)]\)。题目分析对于一个\(i\),以下记成\(n\)。\(n!\)末尾\(0\)的个数取决于\(1\simn\)......
  • [ARC080F] Prime Flip 题解
    Description有无限枚硬币,其中有\(n\)枚硬币\(x_{1\ldotsn}\)。初始时正面朝上,其余均为背面朝上,每次可以选择一段区间\([l,r]\),将区间内所有硬币翻转,其中\(r-l+1\)为一个奇质数。问最少多少次能将所有硬币全部翻为背面朝上。\(1\leqn\leq100,1\leqx_1\leqx_2\leq\ld......
  • CF369D Valera and Fools 题解
    传送门LuoguCodeforces题意简述有\(n\)个傻子智者站成一排,每人手中有\(k\)发子弹,每次每人会向除自己外编号最小的人开枪,第\(i\)个人开枪的命中率为\(p_i\%\),剩余最多一人时结束,问有多少种可能的局面。解法说明从题目要求中可以发现,每次一定是编号最小的人向编号第二......
  • 优化爬虫体验:揭秘IP重复率过高问题解决方案
    在当今信息爆炸的时代,网络中蕴藏着大量宝贵的数据,而爬虫技术成为我们提取这些数据的重要工具。然而,随着爬虫的广泛使用,IP重复率高的问题也随之而来。本篇博文将揭秘解决这一问题的关键方法——使用IP代理。一、IP高重复问题带来的挑战&nbsp;被封禁风险:当一个IP在短时间内频......
  • 优化爬虫体验:揭秘IP重复率过高问题解决方案
    在当今信息爆炸的时代,网络中蕴藏着大量宝贵的数据,而爬虫技术成为我们提取这些数据的重要工具。然而,随着爬虫的广泛使用,IP重复率高的问题也随之而来。本篇博文将揭秘解决这一问题的关键方法——使用IP代理。一、IP高重复问题带来的挑战&nbsp;被封禁风险:当一个IP在短时间内频......
  • 优化爬虫体验:揭秘IP重复率过高问题解决方案
    在当今信息爆炸的时代,网络中蕴藏着大量宝贵的数据,而爬虫技术成为我们提取这些数据的重要工具。然而,随着爬虫的广泛使用,IP重复率高的问题也随之而来。本篇博文将揭秘解决这一问题的关键方法——使用IP代理。一、IP高重复问题带来的挑战&nbsp;被封禁风险:当一个IP在短时间内频......
  • 题解:P10732 [NOISG2019 Prelim] Palindromic FizzBuzz
    题解:P10732[NOISG2019Prelim]PalindromicFizzBuzz题意题意十分明了,给予你一个区间,判断区间中每一个数是否是回文数。思路思路比较简单,首先将每一个数按每一位放入一个数组中,顺序无论由前到后和由后到前都可以。接下来将数组折半循环,判断前后是否一样。一样的话是回文数,......
  • 题解:P8144 [JRKSJ R4] BBWWBB
    思路分析题意可得,白方必定不会胜利,只能尽量让游戏无限进行下去。那么我们只考虑黑方能否胜利。若想让戏能无限进行下去,必须满足以下条件。白方先手。若黑方先手必然可以吃掉一个白方,白方仅有一个棋子,必输。白方第一轮可以吃掉一颗黑方。因为只有\(3,4\)是白方,所以......
  • 洛谷CF1342B Binary Period题解
    原题解和原题。这道题比较水。这道题分两种情况,分别为$t$由一种字符构成和由两种字符构成两种情况。$t$只有$0$或$1$。此时的$k$就是$1$,直接输出$t$就是最好的选择。$t$既有$0$又有$1$。此时的$k$为$2$,字符串由01或10构成。我们设$a_i$为字符串......
  • 题解与求助 P2347 [NOIP1996 提高组] 砝码称重
    P2347[NOIP1996提高组]砝码称重题目描述设有$1\mathrm{g}$、$2\mathrm{g}$、$3\mathrm{g}$、$5\mathrm{g}$、$10\mathrm{g}$、$20\mathrm{g}$的砝码各若干枚(其总重$\le1000$),可以表示成多少种重量?输入格式输入方式:$a_1,a_2,a_3,a_4,a_5,a_6$(表示$1\mathrm{......