zoukankan      html  css  js  c++  java
  • 「BZOJ1954」Pku3764 The xor – longest Path

    zz:http://hzwer.com/5632.html
    给定一棵n个点的带权树,求树上最长的异或和路径
    Input
    The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.
    Output
    For each test case output the xor-length of the xor-longest path.
    Sample Input
    4
    1 2 3
    2 3 4
    2 4 6
    Sample Output
    7

    HINT

    The xor-longest path is 1->2->3, which has length 7 (=3 ⊕ 4)
    注意:结点下标从1开始到N….
    求出根到每个结点的边权异或和
    问题转换为任选两点,异或和最大
    trie的经典?应用
    在trie上从插入所有权值,再查询每个权值。。。(从高位到低位)
    查询x的时候,每一位尽量走与x该位不同的结点

    #include<bits/stdc++.h>
    using namespace std;
    #define node edge[i].to
    int trie[4000000][2],n,dis[100001],head[100001],cnt,tot;
    struct tu{
        int to,pre,f;
    }edge[200000];
    inline void insert(int x)
    {
        int p=0;
        for(int i=31;i>=0;i--)
    	{
            bool f=((x&(1<<i))!=0);
            if(!trie[p][f])trie[p][f]=++tot;
            p=trie[p][f];
        }
    }
    inline void add(int x,int y,int z)
    {
        edge[++cnt].f=z;
        edge[cnt].to=y;
        edge[cnt].pre=head[x];
        head[x]=cnt;
    }
    inline void dfs(int x,int fa)
    {
        insert(dis[x]);//加入到TRIE中 
        for(int i=head[x];i;i=edge[i].pre)
    	{
            if(node==fa)continue;
            dis[node]=dis[x]^edge[i].f;
            //求出权值,等下加入到TRIE中 
            dfs(node,x);
        }
    }
    inline int find(int x)
    {
        int ans=0,p=0;
        for(int i=31;i>=0;i--){
            bool f=((x&(1<<i))==0);
            if(trie[p][f])
    		{
                ans+=1<<i;
                p=trie[p][f];
            }
            else p=trie[p][f^1];
        }
        return ans;
    }
    int ans;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<n;i++)
    	{
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        dfs(1,0);//遍历树 
        for(int i=1;i<=n;i++)
    	{
            ans=max(ans,find(dis[i]));//查询,并求最大值 
        }
        printf("%d
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    浅析几种常用坐标系和坐标转换
    windows live message 无法安装
    解决英文版XP下的PL/SQL Developer的中文乱码问题
    C# static 用法
    用plsql登陆oracle,创建用户赋予权限
    Silverlight Map 技术点总结
    【OCP12c】CUUG 071题库考试原题及答案解析(20)
    【OCP12c】CUUG 071题库考试原题及答案解析(15)
    【OCP12c】CUUG 071题库考试原题及答案解析(14)
    【OCP12c】CUUG 071题库考试原题及答案解析(17)
  • 原文地址:https://www.cnblogs.com/cutemush/p/12526308.html
Copyright © 2011-2022 走看看