码迷,mamicode.com
首页 > 其他好文 > 详细

【数据结构】trie树

时间:2019-08-29 11:35:42      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:space   pos   span   mat   记录   关系   trie树   for   ==   

一个处理字符串查找xort问题的常用工具

1>最长异或路径

给定一棵n个点的带权树,结点下标从1开始到N。寻找树中找两个结点,求最长的异或路径。

异或路径指的是指两个结点之间唯一路径上的所有边权的异或。

1n100000

0w<2^31

 

题意:
一颗最小生成树,带边权
求 所有路径中,边权异或后得到的值,最大是多少

1)最小生成树,那就先拎出来一个顶点

2)从顶点,分出一条条独立的路径

3)这些路径的起点都是rt,所以每条路径的异或结果都容易记录,记为xo[i](rt->i)

 

4)尝试将以rt为起点的路径,与其他路径的异或结果建立关系,发现xo(i->j)=xo(rt->i)^xo(rt->j) (rt,i,j的关系任意)

5)肯定不会去枚举,那么我们把xo(rt->i)的值,按照高位到低位的顺序,放在字母树上

6)然后用xo(rt->i)去找,每次找最大值

7)一个ans记录每次的最大值,中的最大值

8)输出ans

#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;
int n;
const int N=100003;
struct node
{
    int v,w;
    node(int vv,int ww)
    { v=vv,w=ww; }
    node(){}
};
vector <node > g[N];

int xo[N];
void dfs(int nw,int pre)
{
    int sz=g[nw].size() ;
    for(int i=0;i<sz;i++)
    {
        node t=g[nw][i];
        if(t.v ==pre) continue;
        
        xo[t.v ]=xo[nw]^t.w ;
        dfs(t.v ,nw );
    }
}

int rt;
int trie[N*31][2],cnt;
void build(int x)
{
    int pos=rt;
    for(int i=1<<30;i;i>>=1)
    {
        bool tt=i&x;
        if(!trie[pos][tt]) trie[pos][tt]=++cnt;
        pos=trie[pos][tt];
    }
}

int ans;
int query(int x)
{
    int pos=rt,as=0;
    for(int i=1<<30;i;i>>=1)
    {
        bool tt=x&i;
        if(trie[pos][tt^1]) pos=trie[pos][tt^1],as+=i;
        else pos=trie[pos][tt];
    }
    return as;
}

int main()
{
    scanf("%d",&n);
    for(int i=1,u,v,w;i<n;i++)
        scanf("%d%d%d",&u,&v,&w),
        g[u].push_back(node(v,w)),g[v].push_back(node(u,w)); 
    
    dfs(1,0);
    for(int i=1;i<=n;i++) build(xo[i]);
    
    for(int i=1;i<=n;i++) 
        ans=max(ans,query(xo[i]));
    printf("%d\n",ans);
    
    return 0;
}

 

【数据结构】trie树

标签:space   pos   span   mat   记录   关系   trie树   for   ==   

原文地址:https://www.cnblogs.com/xwww666666/p/11428373.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!