最长异或路径java_最长异或路径

题目链接

前置知识

什么是异或? -----如果二进制下同一位不相同,则为\(1\),否则为\(0\)

trie树

基本位运算

对于同一条边异或两次,相当于没有进行异或,我们将dis[i]表示为从i点到根节点的路径异或和。则问题转化为了求两点的dis异或最大值

我们可以根据dis构建一颗01 trie树(自行百度)

贪心的想,对于一个数X,我们对于dis[i]^x最大,则每次往x相反的值选。

及如果x这一位是1,我们在trie树上往0跑,反之往1跑。这样的一定是最大的。

code

#include

#define int ll

#define rg register

#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);

using namespace std;

typedef long long ll;

const int N=1000010;

int read(){

int x=0,f=1;

char c=getchar();

while(c'9') f=(c=='-')?-1:1,c=getchar();

while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();

return f*x;

}

int dis[N],head[N],cnt,tot=1;

struct node {

int to,next,v;

}b[N<<1];

void dfs(int x,int fa){

for(int i=head[x];i;i=b[i].next){

int v=b[i].to;

if(v==fa)

continue;

dis[v]=dis[x]^b[i].v;

dfs(v,x);

}

}

void add(int x,int y,int v){

b[++cnt].to=y;

b[cnt].next=head[x];

b[cnt].v=v;

head[x]=cnt;

}

struct node1 {

int ch[2];

}a[N<<2];

void build(int x){

int u=1;

for(int i=32;i>=0;i--){

int c=(x>>i)&1;

if(!a[u].ch[c])

a[u].ch[c]=++tot;

u=a[u].ch[c];

}

}

int find(int x){

int u=1,ans=0;

for(int i=32;i>=0;i--){

int c=((x>>i)&1)^1;

if(a[u].ch[c])

u=a[u].ch[c],ans+=1<

else

u=a[u].ch[c^1];

}

return ans;

}

main(){

int n=read(),x,y,z,ans=0;

for(int i=1;i

x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);

dfs(1,0);

for(int i=1;i<=n;i++)

build(dis[i]);

for(int i=1;i<=n;i++)

ans=max(ans,find(dis[i]));

printf("%lld",ans);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值