zoukankan      html  css  js  c++  java
  • 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
    ",maxx);
        }
        return 0;
    }
    
  • 相关阅读:
    多线程下单例模式:懒加载(延迟加载)和即时加载
    Java 线程同步
    java 多线程之wait(),notify,notifyAll(),yield()
    序列化和反序列化及线程实现方式
    错题解析
    错题解析
    考试:错题总结
    测试:错题总结
    hashCode与equals的区别与联系
    @Not
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754824.html
Copyright © 2011-2022 走看看