题目链接:http://poj.org/problem?id=3764

分析:好题!武森09年的论文中有道题CowXor,求的是线性结构上的,连续序列的异或最大值,用的办法是先预处理出前n项的异或值,然后在这些值中找出两个值的异或值最大。是基于这样的一个原理,相同段的异或值为0。这题在树中找两个节点,两个节点间有唯一路径(因为是树),把路径不断做异或,异或完后求最大的。数据是10万,O(n2)算法超时。我们知道异或有这样的性质:a^b = (a^c)^(b^c),这样就可以考虑找出a与b公共的c,实际上就是求出从根节点到每个节点的异或值,这样任意两个点做异或,即是他们之间的异或路径(相同部分异或抵消了)。实际上又回到了n(n>100000)个数中找两个值的异或值最大。n^2遍历肯定不行了,这里我们用字典树+贪心优化。即建立一棵trie树每层只有0和1;然后将每个点到达根节点的异或和(这里dfs就行)insert进trie树,然后对于每个点从高位往低位一层层在字典树中尽量找与它相异的值(相异为1嘛,且任意每层取一个数形成的二进制数都是之前插进去的),这样找得下来的值至少大于原值,必定能找出最优值,复杂度(n*30)。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define inf 1<<30
#define mod 1000000007
#define N 100010
using namespace std;
struct edge
{
int v,w,next;
edge(){}
edge(int v,int w,int next):v(v),w(w),next(next){}
}e[N<<];
int head[N],vis[N],nor[N],tot;
void addedge(int u,int v,int w)
{
e[tot]=edge(v,w,head[u]);
head[u]=tot++;
}
void dfs(int u,int w)
{
vis[u]=;nor[u]=w;
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v;
if(vis[v])continue;
dfs(v,e[i].w^w);
}
}
struct Trie
{
int next[N<<][];
int root,L;
int newnode()
{
next[L][]=next[L][]=-;
return L++;
}
void init()
{
L=;
root=newnode();
}
void insert(int x)
{
int now=root;
for(int i=;i>=;i--)
{
int num=(<<i)&x?:;
if(next[now][num]==-)
next[now][num]=newnode();
now=next[now][num];
}
}
int find(int x)
{
int now=root,res=;
for(int i=;i>=;i--)//从二进制的第31位到第1位查找最大异或值
{
int num=(<<i)&x?:;//获取num的二进制数的第i+1位上的数字的非
if(next[now][num]!=-)//如果字典树有要查找的数即有相异的数
{
res|=<<i;//加上该位的权值
now=next[now][num];//进入下一层
}
else now=next[now][!num];//如果没有,则按num当前位上的数字进入下一层查找
}
return res;
}
}trie;
int main()
{
int n,u,v,w;
while(scanf("%d",&n)>)
{
memset(vis,,sizeof(vis));
memset(head,-,sizeof(head));
tot=;trie.init();
for(int i=;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
dfs(,);
int ans=,mx;
for(int i=;i<n;i++)
{
trie.insert(nor[i]);
mx=trie.find(nor[i]);
ans=max(ans,mx);
}
printf("%d\n",ans);
}
}

poj3764(dfs+Trie树+贪心)的更多相关文章

  1. 【BZOJ3261】最大异或和 Trie树+贪心

    [BZOJ3261]最大异或和 Description 给定一个非负整数序列 {a},初始长度为 N.       有   M个操作,有以下两种操作类型:1 .A x:添加操作,表示在序列末尾添加一个 ...

  2. [SCOI2016] 背单词 (Trie 树,贪心)

    题目链接 大致题意 给你 \(n\) 个字符串, 要求你给出最小的代价. 对于每个字符串: 1.如果它的后缀在它之后,那么代价为 \(n^2\). 2.如果一个字符串没有后缀,那么代价为 \(x\), ...

  3. 51nod 1526 分配笔名(Trie树+贪心)

    建出Trie树然后求出一个点子树中有多少笔名和真名.然后贪心匹配即可. #include<iostream> #include<cstring> #include<cst ...

  4. BZOJ4567 [Scoi2016]背单词 【trie树 + 贪心】

    题目链接 BZOJ4567 题解 题意真是鬼畜= = 意思就是说我们应先将一个串的所有后缀都插入之后再插入这个串,产生代价为其到上一个后缀的距离 我们翻转一下串,转化为前缀,就可以建\(trie\)树 ...

  5. 【bzoj3261】【最大异或和】可持久化trie树+贪心

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61705397 Description 给定一个非 ...

  6. POJ 3764 DFS+trie树

    题意: 给你一棵树,求树中最长的xor路径.(n<=100000) 思路: 首先我们知道 A xor B =(A xor C) xor (B xor C) 我们可以随便选一个点DFS 顺便做出与 ...

  7. [CSP-S模拟测试]:big(Trie树+贪心)

    题目描述 你需要在$[0,2^n)$中选一个整数$x$,接着把$x$依次异或$m$个整数$a_1~a_m$.在你选出$x$后,你的对手需要选择恰好一个时刻(刚选完数时.异或一些数后或是最后),将$x$ ...

  8. 【BZOJ4260】Codechef REBXOR Trie树+贪心

    [BZOJ4260]Codechef REBXOR Description Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,…,AN. Output ...

  9. 【HDU6687】Rikka with Stable Marriage(Trie树 贪心)

    题目链接 大意 给定\(A,B\)两个数组,让他们进行匹配. 我们称\(A_i\)与\(B_j\)的匹配是稳定的,当且仅当目前所剩元素不存在\(A_x\)或\(B_y\)使得 \(A_i\oplus ...

随机推荐

  1. Windows Service的安装卸载 和 Service控制

    原文 Windows Service的安装卸载 和 Service控制 本文内容包括如何通过C#代码安装Windows Service(exe文件,并非打包后的安装文件).判断Service是否存在. ...

  2. 性能测试之LoardRunner 手动关联二

    概述: 1.如果寻找左右边界值 2.关联函数详解 以下是详细介绍 1.如果寻找左右边界值 <以login 为例> Step1.录制两份相同的业务流程的的脚本,输入的数据要相同 Step2. ...

  3. zipalign 文件路径问题

    在使用zipalign,对Android程序进行打包,有些时候可能提示找不到zipalign ,可以复制一份放在相应的文件夹就行了 windows: 如果缺少zipalign,在网上找到相应的文件放在 ...

  4. Usaco 1.3.2 修理牛棚(Barn Repair)

      Barn Repair 题意:在一个夜黑风高,下着暴风雨的夜晚,农民约翰的牛棚的屋顶.门被吹飞了. 好在许多牛正在度假,所以牛棚没有住满. 剩下的牛一个紧挨着另一个被排成一行来过夜. 有些牛棚里有 ...

  5. Swift - 高级运算符介绍

    除了基本运算符之外,Swift还支持位运算和位移运算,包括:   1,按位取反运算:操作符是 ~ 2,按位与运算:操作符是 & 3,按位或运算:操作符是 | 4,按位异或运算:操作符是 ^ 5 ...

  6. POJ 3007 Organize Your Train part II

    题意: 如上图所示,将一个字符串进行分割,反转等操作后不同字符串的个数: 例如字符串abba:可以按三种比例分割:1:3:2:2:3:1 部分反转可以得到如下所有的字符串: 去掉重复可以得到六个不同的 ...

  7. java面向对象下:Java数据库编程

    19.Java数据库编程: JDBC概述:        JDBC(Java Database Connection)是java中提供的一套数据库编程API,它定义了一套用来访问数据库的标准Java类 ...

  8. [置顶] head first 设计模式之----Observer pattern

    浅谈设计模式之----观察者模式      观察者模式也是我们日常程序编写中碰到比较多的一种设计模式.首先,所谓观察者模式定义就是指:在对象之间定义了一对多的依赖,这样一来,当一个对象的状态发生变化的 ...

  9. 由一道淘宝面试题到False sharing问题

    今天在看淘宝之前的一道面试题目,内容是 在高性能服务器的代码中经常会看到类似这样的代码: typedef union { erts_smp_rwmtx_t rwmtx; byte cache_line ...

  10. iOS应用开发详解

    <iOS应用开发详解> 基本信息 作者: 郭宏志    出版社:电子工业出版社 ISBN:9787121207075 上架时间:2013-6-28 出版日期:2013 年7月 开本:16开 ...