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;
}
标签:int,题解,ll,Tree,fa,CF1624G,MinOr
From: https://www.cnblogs.com/BigSmall-En/p/16749619.html