P4551 最长异或路径

题目传送门

一个很费脑子的性质:两个点的异或最长路=两个点分别到根节点异或值的异或值,因为在0-1trie这两个点LCA除外的路径是重复的,一个数异或自己为0

所以思路就是把输入的点用dfs求一遍到根节点的异或值,然后建立0-1trie 后找最大值

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
template<class T> inline T &read(T &x){
    bool f=1;x=0;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) f^=(ch=='-');
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
    return f?x:(x=-x);
}
struct node{
    int v,w,nxt;
}edge[N];
int head[N],sum[N],cnt;
void add(int u,int v,int w){
    edge[cnt].nxt=head[u],edge[cnt].v=v,edge[cnt].w=w,head[u]=cnt++;
}
void dfs(int x,int fa){
    for(int i=head[x];~i;i=edge[i].nxt){
        int y=edge[i].v,w=edge[i].w;
        if(y!=fa){
            sum[y]=sum[x]^w;
            dfs(y,x);
        }
    }
}
struct trie{
    int ch[2];
}t[N];
int tot,n,u,v,w,ans;
void build(int val,int x){
    for(int i=(1<<30);i;i>>=1){
        bool c=val&i;//取出二进制下这个数的当前位置
        if(!t[x].ch[c]){//x=0时说明这个根节点是一个虚拟的,左0右1
        //没有就往下延伸
            t[x].ch[c]=++tot;
        }
        x=t[x].ch[c];//因为每次都建一个数,所以这里建完就往下跳是正确的
    }
}
int query(int val,int x){
    int ans=0;
    for(int i=(1<<30);i;i>>=1){
        bool c=val&i;
        if(t[x].ch[!c]){//如果这一位可以进行异或就沿着这一条往下走
            ans+=i;//这里为什么加i,取相反的数肯定属于答案的一部分,i又是当前位的数字
            x=t[x].ch[!c];
        }
        else x=t[x].ch[c];//否则就沿着另一条路往下走
    }
    return ans;
}
int main(){
    memset(head,-1,sizeof head);
    read(n);
    for(int i=1;i<n;++i){
        read(u),read(v),read(w);
        add(u,v,w),add(v,u,w);
    }
    dfs(1,-1);//预处理出每一个节点到根的异或和
    for(int i=1;i<=n;++i) build(sum[i],0);//建立trie树
    for(int i=1;i<=n;++i) ans=max(ans,query(sum[i],0));
    printf("%d\n",ans);
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值