• poj3764-The xor-longest Path


    Description

    In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:

    ⊕ is the xor operator.

    We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?  

    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
    0 1 3
    1 2 4
    1 3 6
    

    Sample Output

    7

    Hint

    The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)

    题意:求树上两点路径的异或和的最大值
    
    用d[x]表示根到x路径上所有边权的异或和,由异或的性质,x到y路径上所有边权的异或和等于d[x] xor d[y],所以就是在d[0]-d[n-1]中找两个数,使得异或之后最大。
    把每个整数看作长度为31的01串(数值较小的在前面补0),然后插入到一棵字典树中
    每次查找一个数,先尝试沿着与当前位相反的字符指针向下访问,如果没有就访问相同的,这样构造出来的一定是与当前查找的数做xor运算结果最大的。
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    //#include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2e5+100;
    int n,cnt,tot;
    int last[N],d[N];
    struct tree{
        int v,nex,w;}t[N*2];
    int trie[N*32][2];
    void add(int x,int y,int z)
    {
        cnt++;
        t[cnt].v=y;
        t[cnt].nex=last[x];
        last[x]=cnt;
        t[cnt].w=z;
    }
    void dfs(int x,int fa,int dis)
    {
        d[x]=dis;
        for (int i=last[x];i;i=t[i].nex)
        {
            if (t[i].v==fa) continue;
            dfs(t[i].v,x,dis^t[i].w);
        }
    }
    
    void Insert(int x)
    {
        int p=0,now;
        for (int i=31;i>=0;i--)
        {
            now=(x>>i)&1;
            if (!trie[p][now]) trie[p][now]=++tot;
            p=trie[p][now];
        }
    }
    int fund(int x)
    {
        int p=0,now,ret=0;
        for (int i=31;i>=0;i--)
        {
            now=!((x>>i)&1);
            ret<<=1;
            if (trie[p][now])
            {
                p=trie[p][now];
                ret++;
            }
            else p=trie[p][!now];
        }
        return ret;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            memset(last,0,sizeof(last));
            memset(trie,0,sizeof(trie));
            cnt=0; tot=0;
    
            int x,y,z;
            for (int i=1;i<n;i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                add(x,y,z); add(y,x,z);
            }
            d[0]=0;
            dfs(0,-1,0);
    
            int ans=0;
            for (int i=0;i<n;i++) Insert(d[i]);
            for (int i=0;i<n;i++) ans=max(ans,fund(d[i]));
            printf("%d
    ",ans);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    js判断值是否为数字
    人脸识别 python调用face++ 功能测试
    【转载】Cesium基础使用介绍
    数据分析R&Python-Rpy2包环境配置
    VR/AR软件—Mirra测试(截至2017/11/13),使AR/VR创作更加便捷
    Cesium左右立体视觉续篇——遗留问题(渲染错误)以及临时替代方案
    在CesiumVR基础上实现3D左右立体视觉
    关于css样式的选择问题
    圣杯布局和双飞翼布局
    冒泡排序法
  • 原文地址:https://www.cnblogs.com/tetew/p/9677430.html
Copyright © 2020-2023  润新知