poj3764

  题意就是给一棵树,然后让你求最大的路经异或和是多少,一条路径的异或和是该路径上的边对应的边权的异或和。

  因为^具有自反性,即a^a=0,所以我们只需要dfs处理出根节点到每个点的路径的异或和dp[i],那么u至v的路径的异或和即等于       dp[u]^dp[v],然后把dp[i]都放入01字典树里,枚举起点i,求与dp[i]异或得到的最大的数,然后取最大值即可。

#include<stdio.h>
#include<iostream>
#include<vector>
using namespace std;
const int maxn=1e5+10;
struct node
{
    int val,cnt,son[2];
    void reset()
    {
        val=cnt=son[0]=son[1]=0;
    }
}tree[maxn*32];
struct edge
{
    int v,w,nxt;
    edge(int v=0,int w=0,int nxt=0)
    {
        this->v=v;
        this->w=w;
        this->nxt=nxt;
    }
}e[2*maxn];
int dp[maxn],head[maxn],n,cnt;
void myinsert(int x)
{
    int r=0,v;
    for(int i=31;i>=0;i--)
    {
        v=(x>>i)&1;
        if(!tree[r].son[v])
        {
            tree[++cnt].reset();
            tree[r].son[v]=cnt;
        }
        if(r!=0)
            tree[r].cnt++;
        r=tree[r].son[v];
    }
    tree[r].val=x;
    tree[r].cnt++;
}
int query(int x)
{
    int r=0,v;
    for(int i=31;i>=0;i--)
    {
        v=(x>>i)&1;
        if(tree[r].son[v^1]&&tree[tree[r].son[v^1]].cnt)
            r=tree[r].son[v^1];
        else
            r=tree[r].son[v];
    }
    return tree[r].val^x;
}
void dfs(int now,int fa)
{
    int v,w;
    for(int i=head[now];i!=-1;i=e[i].nxt)
    {
        v=e[i].v;
        w=e[i].w;
        if(v==fa) continue;
        dp[v]=dp[now]^w;
        dfs(v,now);
    }
}
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
    return x*f;
}
int main()
{
    int maxx;
    while(scanf("%d",&n)!=EOF)
    {

        tree[0].reset();
        cnt=0;
        maxx=0;
        for(int i=0;i<n;i++) head[i]=-1;
        for(int i=1,cnt=0;i<n;i++)
        {
            int u,v,w;
            u=read();
            v=read();
            w=read();
            e[cnt]=edge(v,w,head[u]);
            head[u]=cnt++;
            e[cnt]=edge(u,w,head[v]);
            head[v]=cnt++;
        }
        dfs(0,-1);
        for(int i=0;i<n;i++)
            myinsert(dp[i]);
        for(int i=0;i<n;i++)
        {
            maxx=max(maxx,query(dp[i]));
        }
        printf("%d\n",maxx);
    }
    return 0;
}

 

posted @ 2019-01-23 22:33  eason99  阅读(72)  评论(0编辑  收藏  举报