POJ 3764 DFS+trie树
2016-07-17 23:27
323 查看
题意:
给你一棵树,求树中最长的xor路径。(n<=100000)
思路:
首先我们知道 A xor B =(A xor C) xor (B xor C)
我们可以随便选一个点DFS 顺便做出与这个点连接的其它点的xor长度
但是
枚举起点&重点+判断会TLE
所以呢 随后 就是重头戏了:trie树
这是一棵神奇的树 (莫名想到了“这是一个神奇的网站”)
我们可以从高位往低位插这个点的xor的值。(数字前面可以补零)
之后是查找 由于异或的性质,我们可以得到:当此位数字不相同时 xor得到的值最大,那不就好说了嘛。
每回寻找树上有没有与这一位不相同的值的节点
1.若有,w|=(1 << i) 。按此方向向下寻找
2.若没有,继续顺着trie树往下走
注意是多case。
注意清空数组,ans、归零什么的
PoPoQQQ大爷在这里都有惨痛的经历。
// by SiriusRen #include <cstdio> #include <cstring> #include <algorithm> #define N 305000 using namespace std; int first[N],next[N],v[N],w[N],W[N],trie[N*10][2]; int xx,yy,zz,n,tot,cnt,ans; bool vis ; void add(int x,int y,int z){ v[tot]=y,w[tot]=z; next[tot]=first[x],first[x]=tot++; } void dfs(int x){ for(int i=first[x];~i;i=next[i]) if(!vis[v[i]]){ vis[v[i]]=1; W[v[i]]=W[x]xor w[i]; dfs(v[i]); } } void insert(int x){ int jy=0; for(int i=30;i>=0;i--){ int temp=x&(1<<i)?1:0; if(trie[jy][temp]==0) trie[jy][temp]=++cnt; jy=trie[jy][temp]; } } int find(int x){ int jy=0,w=0; for(int i=30;i>=0;i--){ int temp=x&(1<<i)?1:0; if(trie[jy][!temp]) w|=(1<<i),jy=trie[jy][!temp]; else jy=trie[jy][temp]; } return w; } int main(){ while(~scanf("%d",&n)){ memset(first,-1,sizeof(first)); memset(trie,0,sizeof(trie)); memset(vis,0,sizeof(vis)); memset(W,0,sizeof(W)); ans=tot=cnt=0; for(int i=1;i<n;i++){ scanf("%d%d%d",&xx,&yy,&zz); add(xx,yy,zz),add(yy,xx,zz); } dfs(xx); for(int i=0;i<n;i++)insert(W[i]),ans=max(ans,find(W[i])); printf("%d\n",ans); } }
万朵红中一点蓝。
相关文章推荐
- spring为什么实现接口?
- MYSQL基础笔记(四)-数据基本操作
- NP-Hard问题浅谈
- Elasticsearch学习(二)
- day_7-acm 周赛总结(1)
- 基于maven快速搭建自定义的karaf开发调试环境
- Java加密问题的的_改进
- UIViewController介绍:3-控制器切换(使用StoryBoard)
- Java加密问题的的_实现
- lua 语法
- docker踩坑记
- asp.net对象——Response、Request
- Nginx 的 Echo 模块 —— echo-nginx-module(转)
- Java基础14----正则表达式、Math类、System类、BigInteger、日期类
- 私有Pods封装个推SDK功能(解决方案)
- Linux下编译安装qemu和libvirt
- BestCoder 2nd Anniversary 1001~1003
- Js基础学习之 -- DOM兼容 根据标签、类名获取节点函数封装
- 开源的目的
- 基于SteamVR开发Htcvive应用-helloworld(一)