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;
    }
    

      

  • 相关阅读:
    笔试题 9.11
    shell脚本编程
    android源码中用到的设计模式
    struts2.0的工作流程
    无奈的信息产业部备案网站流程
    VS2005调试时弹出“无法附加。绑定句柄无效”对话框
    彻底删除项目的VSS源代码管理信息
    软件版本详细介绍
    导入SourceSafe过程中项目结构无法修改问题的解决方案
    建立良好的客户关系=节约项目成本
  • 原文地址:https://www.cnblogs.com/cutemush/p/12526308.html
Copyright © 2011-2022 走看看