Gushing over Pr|

BigSmall_En

园龄:3年2个月粉丝:3关注:5

2022-10-02 22:11阅读: 58评论: 0推荐: 0

CF1624G MinOr Tree 题解

CF1624G MinOr Tree

给定 \(n\) 个点,\(m\) 条边,求在或运算小的最小生成树

考虑二进制拆位,从高位玩往地位贪心,如果答案第 \(i\) 位可以为 \(0\),后 \(i-1\) 取值无论是多少都比第 \(i\)\(1\) 更优。

因此假设当前考虑第 \(k\) 位,则我们需要判断在满足高位的情况下,第 \(k\) 位能否取到 \(0\),则假设已经确定的高位的结果为 \(x\),即应当满足 \(x|w<x+2^{k}\)

具体见代码

const int N=200005;
int n,m,fa[N];
inline int fidf(int x){return x==fa[x]?x:fa[x]=fidf(fa[x]);}
struct sgline{int u,v;ll w;}line[N];
inline bool check(ll las,ll loc){
	int cnt=0;
	for(int i=1;i<=n;++i)fa[i]=i;
	for(int i=1;i<=m;++i){
		if((line[i].w|las)>=(las+(1ll<<loc)))continue;
		int fu=fidf(line[i].u),fv=fidf(line[i].v);
		if(fu==fv)continue;
		fa[fu]=fv;
		if(++cnt==n-1)break;
	}
	return cnt==n-1;
}
int main(){
	int T=read();
	while(T--){
		n=read(),m=read();
		for(int i=1;i<=m;++i){
			line[i].u=read(),line[i].v=read();
			line[i].w=read();
		}
		ll ans=0;
		for(ll i=30;i>=0;--i){
			if(!check(ans,i))
				ans|=(1ll<<i);
		}
		printf("%lld\n",ans);
	}
	return 0;
}

本文作者:BigSmall_En

本文链接:https://www.cnblogs.com/BigSmall-En/p/16749619.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   BigSmall_En  阅读(58)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起