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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步