首页 > 其他分享 >ABC245G Foreign Friends 题解 / 二进制分组

ABC245G Foreign Friends 题解 / 二进制分组

时间:2024-09-24 16:25:59浏览次数:9  
标签:颜色 二进制 int 题解 源点 Foreign read ABC245G 位上

ABC245G Foreign Friends 题解

回顾一下二进制分组。

题目大意

给定一张 \(N\) 个点 \(M\) 条边的无向图,及 \(L\) 个特殊点。每个点有颜色 \(C_i\)。求每个点到离他最近的与他颜色不同特殊点的距离。

Solve

两个点颜色不同,等价于他们的颜色在二进制下至少有一位不同。

所以我们考虑把所有点按颜色二进制分组。枚举位数 \(x\),把颜色第 \(x\) 位上是 \(1\) 的和是 \(0\) 的点分为两组。

跑两次多源最短路,第一次把第 \(x\) 位上是 \(1\) 的那一组里的特殊点作为源点去跑,然后用求得的最短路去更新第 \(x\) 位上是 \(0\) 的那一组里的点的答案。

第二次反过来,把第 \(x\) 位上是 \(0\) 的特殊点作为源点,更新 \(1\) 组的答案。

多源最短路也可以用超级源点代替。

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read()
{
	short f=1;
	int x=0;
	char c=getchar();
	while(c<'0'||c>'9')	{if(c=='-')	f=-1;c=getchar();}
	while(c>='0'&&c<='9')	x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
const int N=1e5+10,inf=1e18;
int n,m,dis[N],k,l,a[N],ans[N];
typedef pair<int,int> PII;
vector<PII>e[N];
priority_queue<PII,vector<PII>,greater<PII>>q;
inline void dij(int s)
{
	for(int i=1;i<=n;i=-~i)	dis[i]=inf;
	q.push({dis[s]=0,s});
	while(!q.empty())
	{
		int u=q.top().second,d=q.top().first;q.pop();
		if(d>dis[u])	continue;
		for(PII i:e[u])
			if(dis[i.first]>d+i.second)
				q.push({dis[i.first]=d+i.second,i.first});
	}
}
bool tag[N];
inline void solve(int x,bool op)
{
	e[0].clear();
	for(int i=1;i<=n;i=-~i)
		if((a[i]>>x&1)==op&&tag[i])	e[0].push_back({i,0});
	dij(0);
	for(int i=1;i<=n;i=-~i)
		if((a[i]>>x&1)^op)	ans[i]=min(ans[i],dis[i]);
}
signed main()
{
	n=read();m=read();k=read();l=read();
	for(int i=1;i<=n;i=-~i)	a[i]=read(),ans[i]=inf;
	for(int i=1;i<=l;i=-~i)	tag[read()]=1;
	for(int i=1,u,v,w;i<=m;i=-~i)
		u=read(),v=read(),w=read(),
		e[u].push_back({v,w}),e[v].push_back({u,w});
	for(int i=0;i<20;i=-~i)	solve(i,0),solve(i,1);
	for(int i=1;i<=n;i=-~i)
		printf("%lld ",ans[i]<inf?ans[i]:-1);
	return 0;
}

标签:颜色,二进制,int,题解,源点,Foreign,read,ABC245G,位上
From: https://www.cnblogs.com/sorato/p/18429412

相关文章

  • MySQL GROUP BY 分区大小写问题解析
    在数据库操作中,GROUPBY是一个常用的SQL语句,用于根据一个或多个列的值对结果集进行分组。然而,在使用MySQL时,你可能会遇到一个常见问题:大小写敏感性。本文将探讨MySQL中GROUPBY的大小写敏感性问题,并提供一些解决方案。什么是大小写敏感性?在计算机科学中,大小写敏感性是指......
  • Codeforces Round 974 (Div.3) 题解
    CodeforcesRound974(Div.3)题解A.RobinHelps模拟按照题意模拟即可。voidShowball(){intn,k;cin>>n>>k;intcur=0,ans=0;for(inti=0;i<n;i++){intx;cin>>x;if(x>=k)cur+=x;elseif(!x){if(cur>=1)cu......
  • AT_jsc2021_g Spanning Tree 题解
    感觉自己稍微有一点唐了。思路我们首先可以把一定要连的边连起来。这样就变成了一个无向图生成树计数问题。如何求解。使用矩阵树定理!我们可以求出基尔霍夫矩阵,然后跑一遍行列式就可以了。时间复杂度:\(O(n^3)\)。Code#include<bits/stdc++.h>usingnamespacestd;con......
  • Count Equation Solutions 题解
    前言题目链接:洛谷;UVA。题意简述求以下方程解的个数:\[a_1x_1-a_2x_2+a_3x_3-a_4x_4+a_5x_5-a_6x_6=0\]其中\(1\leqx_i\leqm\leq10^2\),\(x_i\in\mathbb{Z}\),多测。题目分析把\(a_2,a_4,a_6\)变成其相反数,变成\(\sum\limits_{i=1}^6a......
  • 题解 [ARC184B] 123 Set
    个人认为思维难点相同的三倍经验:P3226[HNOI2012]集合选数、TFSETS-Triple-FreeSets。区别在于状压DP的方法。我们称不包含质因子\(2\)和\(3\)的数为\(2,3\texttt{-Free}\)的。对于\([1,n]\)内每个\(2,3\texttt{-Free}\)的整数\(u\),可以列出以下的矩阵:\[\begi......
  • NEERC2013题解
    B.BonusCards简单dp一下,记\(f_{ij}\)为前i次有j次分给第一类的概率。最后再算上我在第一类被选上的概率即可。constintN=3005;#defineintlonglongintn,a,b;doublef[N][N],g[N][N];signedmain(void){#ifdefONLINE_JUDGE freopen("bonus.in","r",stdin......
  • 题解:CF888G Xor-MST
    题解:CF888GXor-MST题目大意:给定\(n\)个点的点权,任意两点间边权是点权的异或和。求这张完全图的MST的权值。思路:Boruvka+Trie树+按位贪心。关键就在于如何求出Boruvka中的best数组。考虑对点权建trie树,对于节点\(i\)本轮的连边,就是找“和它最相似”的那......
  • SP1825 FTOUR2 - Free tour II 题解
    题目传送门前置知识点分治|树状数组解法维护点对信息,考虑点分治。本题比luoguP4149[IOI2011]Race多了个前缀查询\(\max\)。套个支持单点修改、区间查询\(\max\)的数据结构即可。直接线段树维护区间\(\max\)貌似会TLE,换成树状数组维护前缀\(\max\)即可。注......
  • LGP3183 题解
    原题链接:P3183[HAOI2016]食物链。难度:Easy。根据定义,食物链是一个DAG,所以可以进行拓扑排序。食物链也就转化成了:图中从一个入度为\(0\)的点到一个出度为\(0\)的点的路径。那么只需要拓扑排序求出所有起点到每个点的路径条数,然后累加出度为\(0\)的点的值即可。需要注......
  • LGP1901 题解
    原题链接:P1901发射站难度:Easy。注意到"最近的且比它高",容易想到用单调栈维护每个能量发射站左右第一个比它高的,最后统计答案即可。具体的令f[i][0/1]表示能量发射站\(i\)右边/左边第一个\(h_x>h_i\)的位置\(x\)。用单调栈从左向右扫一遍,得到f[i][0]。用单调栈从右......