poj2764 The xor-longest Path(Trie)

版权声明:本文为博主原创文章,未经博主允许不得转载,除非先点了赞。 https://blog.csdn.net/A_Bright_CH/article/details/81674207

题意

一颗树n个节点,每个边有个权值,在树上找一条简单路径,使得这条路径上的边权异或值最大。

题解

前缀异或和+trie
设d[x]=d[fa[x]] xor e[k].c,这样做的好处是可以很方便的求出两点路径上边权的异或值wight(x,y)=d[x] xor d[y]。无论是在同一棵子树还是分散在两棵子树中,都适用。
题意就转换成了求n个数中任取两个数的最大异或值。这是个基本题型,这里不再详细分析,不会的请自学

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int power[40];

int d[maxn];
struct edge
{
    int x,y,c,next;
}e[maxn*2];int len,last[maxn];

void ins(int x,int y,int c)
{
    e[++len]=(edge){x,y,c,last[x]};last[x]=len;
}

void dfs(int x,int fa)//处理d数组
{
    for(int k=last[x];k;k=e[k].next)
    {
        int y=e[k].y;
        if(y==fa) continue;
        d[y]=d[x]^e[k].c;
        dfs(y,x);
    }
}

struct trnode
{
    int son[2];
}tr[maxn*32];int trlen;

void insert(int q)
{
    int x=0;
    for(int i=30;i>=0;i--)
    {
        if(q>=power[i])
        {
            q-=power[i];
            if(tr[x].son[1]==0)
            {
                tr[x].son[1]=++trlen;
                tr[trlen].son[0]=tr[trlen].son[1]=0;
            }
            x=tr[x].son[1];
        }
        else
        {
            if(tr[x].son[0]==0)
            {
                tr[x].son[0]=++trlen;
                tr[trlen].son[0]=tr[trlen].son[1]=0;
            }
            x=tr[x].son[0];
        }
    }
}

int find_max(int q)
{
    int x=0,re=0;
    for(int i=30;i>=0;i--)
    {
        if(q>=power[i])//1
        {
            q-=power[i];
            if(tr[x].son[0]!=0)
            {
                re+=power[i];
                x=tr[x].son[0];
            }
            else if(tr[x].son[1]!=0) x=tr[x].son[1];
        }
        else//0
        {
            if(tr[x].son[1]!=0)
            {
                re+=power[i];
                x=tr[x].son[1];
            }
            else if(tr[x].son[0]!=0) x=tr[x].son[0];
        }
    }
    return re;
}

int main()
{
    power[0]=1;for(int i=1;i<=30;i++) power[i]=power[i-1]<<1;
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        trlen=len=0;memset(last,0,sizeof(last));
        for(int i=1;i<n;i++)
        {
            int x,y,c;
            scanf("%d%d%d",&x,&y,&c);
            x++;y++;
            ins(x,y,c);ins(y,x,c);
        }
        d[1]=0;dfs(1,0);
        
        tr[0].son[0]=tr[0].son[1]=0;
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            ans=max(ans,find_max(d[i]));//每次只需要在1~i-1中查找最大xor 
            insert(d[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/A_Bright_CH/article/details/81674207