题意 : 给出一颗无向边构成的树,每一条边都有一个边权,叫你选出一条路,使得此路所有的边的异或值最大。

分析 : 暴力是不可能暴力的,这辈子不可能暴力,那么来冷静分析一下如何去做。假设现在答案的异或值的最大的路的起点和终点分别为 a、b,这个异或值为了方便我用 ⊕(a, b) 表示,那么接下来有一个巧妙的转化 ⊕(a, b) == ⊕(root, a) ^ ⊕(root, b) ,这个转化在 LCA(a, b) == root 的时候明显成立,因为重复的部分会异或两次,相当于没有异或,而LCA(a, b) != root的时候,同样也可以使用上述转化来进行运算,因为这是一棵树,所以最后无论哪两个节点,都至少会有 root 是这两个节点的祖先,因此不必担心 a 和 b 在上述运算出来的结果会有 a 和 b 不联通的情况,那么这题就很好做了,只要从根节点开始DFS,每一次将新节点异或得到新的异或值并丢到字典树里面,这样所有的 ⊕(root, 所有点) 都会到字典树里面去,出来的结果也自然是其中的两个节点一个作为起点一个作为终点出来的路径异或值。表达可能不太好,请见谅,看看代码辅助理解吧……

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<algorithm>
#define LL long long
using namespace std;
;
;
;
int ans;
struct Edge{ int v, Next, weight; };
Edge e[maxn<<];
int Head[maxn];
bool vis[maxn];

inline void Add_Edge(int v, int to, int weight)
{
    e[tot].v = to;
    e[tot].Next = Head[v];
    e[tot].weight = weight;
    Head[v] = tot++;
}

struct Trie
{
    Trie *ch[];
    int v;
    inline void init(){
        ; i<; i++) this->ch[i] = NULL;
        ;
    };
} Heap[maxn<<];
;
Trie *root;
Trie * New()
{
    Heap[node_cnt].init();
    return &Heap[node_cnt++];
}

inline void CreateTrie(int x)
{
    Trie * p = root, *tmp;
    ; i--){
        ;
        if(p->ch[idx] == NULL){
            p->ch[idx] = New();
        }p = p->ch[idx];
    }
    p->v = x;
}

int Query(int x)
{
    Trie *p = root;
    ; i--){
        ;
        ]){
            p = p->ch[idx^];
        }else p = p->ch[idx];
    }
    return (p->v) ^ x;
}
void DFS(int u, int Val)
{
    CreateTrie(Val);///将路径的权值全丢到字典树里面去,代表⊕(root, u)
    vis[u] = true;
    ; i=e[i].Next){
        int v = e[i].v;
        int w = e[i].weight;
        if(!vis[v]){
            ans = max(ans, Query(Val ^ w));///查询更新最值
            DFS(v, Val^w);
        }
    }
}

inline void INIT()
{
    node_cnt = ;
    root = New();
    memset(Head, -, sizeof(Head));
    memset(vis, false, sizeof(vis));
    ans = tot = ;
}

int main(void)
{
    int n;
    while(~scanf("%d", &n)){
        INIT();
        ; i<=n-; i++){
            int u, v, w;
            scanf("%d %d %d" ,&u, &v, &w);
            u++, v++;
            Add_Edge(u, v, w);
            Add_Edge(v, u, w);
        }
        DFS(, );
        printf("%d\n", ans);
    }
    ;
}

瞎 : 想法非常好的题目,利用异或性质转化思想需要学习

POJ 3764 The xor-longest Path ( 字典树求异或最值 && 异或自反性质 && 好题好思想)的更多相关文章

  1. HDU-4825 Xor Sum(字典树求异或最大值)

    题目链接:点此 我的github地址:点此 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整 ...

  2. HDU4825 Xor Sum(字典树解决最大异或问题)

    Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整 ...

  3. poj 3764 The xor-longest Path(字典树)

    题目链接:poj 3764 The xor-longest Path 题目大意:给定一棵树,每条边上有一个权值.找出一条路径,使得路径上权值的亦或和最大. 解题思路:dfs一遍,预处理出每一个节点到根 ...

  4. poj3764 The XOR Longest Path【dfs】【Trie树】

    The xor-longest Path Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10038   Accepted:  ...

  5. 【POJ 3764】 The xor-longest path

    [题目链接] http://poj.org/problem?id=3764 [算法] 首先,我们用Si表示从节点i到根的路径边权异或和 那么,根据异或的性质,我们知道节点u和节点v路径上的边权异或和就 ...

  6. HDU--5269 ZYB loves Xor I (字典树)

    题目电波: HDU--5269 ZYB loves Xor I 首先我们先解决 ai xor aj 每个数转化为二进制  我们用字典树统计 每个节点 0 和 1 的出现的个数 #include< ...

  7. CH 1602 - The XOR Largest Pair - [字典树变形]

    题目链接:传送门 描述在给定的 $N$ 个整数 $A_1, A_2,\cdots,A_N$ 中选出两个进行xor运算,得到的结果最大是多少? 输入格式第一行一个整数 $N$,第二行 $N$ 个整数 $ ...

  8. HDU 5715 XOR 游戏 二分+字典树

    XOR 游戏 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5715 Description 众所周知,度度熊喜欢XOR运算(XOR百科). 今天,它 ...

  9. HDU-4825 Xor Sum,字典树好题!

    Xor Sum 一遍A了之后大呼一声好(keng)题!debug了两小时~~~~百度之星资格赛,可以. 题意:给你一个n个元素的数组,m次查询,每次输入一个数k要求从数组中找到一个数与k异或值最大,输 ...

随机推荐

  1. RabbitMQ使用(上)

    1. 说明 在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的地方, ...

  2. 微PE.PE工具

    1.ZC:想要 干掉Win7x64的密码(没人用的机子,不知道密码,不想重装OS) 1.1.超详细微pe工具箱使用教程 _ 微pe工具箱怎么用.html(http://www.360doc.com/c ...

  3. .net core 学习小结之 Cookie-based认证

    在startup中添加授权相关的管道 using System; using System.Collections.Generic; using System.Linq; using System.T ...

  4. xmake v2.2.9 发布, 新增c++20 modules的实验性支持

    这个版本没啥太大新特性,主要对c++20 modules进行了实验性支持,目前支持clang/msvc编译器,除此之外改进了不少使用体验,并且提高了一些稳定性. 另外,这个版本新增了socket.io ...

  5. JDK,JRE,JVM的区别与联系?

    概念区别 JDK:           Java Develpment Kit java 开发工具JRE:         Java Runtime Environment java运行时环境JVM: ...

  6. HashMap底层为什么一定用数组

    HashMap源码数据结构: Entry[] table = new Entry[capacity]; 其中,Entry就是一个链表节点.如果将数组替换成LinkedList是否可行?如下: List ...

  7. C++中操作符重载的概念

    1,下面的复数解决方案是否可行? 1,代码示例: class Comples { public: int a; int b; }; int main() { Complex c1 = {, }; Co ...

  8. mui前端框架下拉刷新分页加载数据

    前台 mui.init(); (function($) { //阻尼系数 var deceleration = mui.os.ios?0.003:0.0009; $('.mui-scroll-wrap ...

  9. 手写spring事务框架, 揭秘AOP实现原理。

    AOP面向切面编程:主要是通过切面类来提高代码的复用,降低业务代码的耦合性,从而提高开发效率.主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等. AOP实现原理:aop是通过cgli ...

  10. Views的补充

    views的补充 请求头一般与请求内容用/r/n/r/n隔开 请求头包含的内容 request.Meta(...) 一般在下面几种方法里面取不到的东西需要去原生的头里面去取,比如用户的终端类型 req ...