• POJ3764 字典树


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

    题意简单来说就是给你一棵树,从树上找两个点它们之间所有边权的异或值最大。

    假设从根节点到i点的异或值为xor[i],那么从a点到b点的异或值应该是xor[a]^xor[b]吧,因为从根节点到a,b祖先节点会异或掉自身。

    那么我们可以先将树遍历一遍,处理出根节点到每一个点的异或值,然后运用字典树求最大异或二元组的方法得出答案。

    简单说一下如何求最大异或二元组,将每一个点以二进制的形式插入字典树,对于每一个数,沿着它每一位相反的值查找字典树,当然如果字典树没有该节点,就走相同的值的那边,最后异或上查找到的数,就是这个数对应的最大二元组,最后取一个最大值就是答案。

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <list>
    #include <utility>
    #define MAXN 100010
    using namespace std;
    typedef long long LL;
    int n,d[MAXN],tire[32*MAXN][2],tot=1,head[MAXN],cnt=0;
    struct List{
        int v,e,nxt;
    }edge[MAXN*2];
    
    void Dfs(int node,int father)
    {
        for(int i=head[node];i;i=edge[i].nxt)
        {
            int nxt=edge[i].v,len=edge[i].e;
            if(nxt!=father)
            {
                d[nxt]=d[node]^len;
                Dfs(nxt,node);
            }
        }
    }
    
    void Insert(int x)
    {
        int p=1;
        for(int i=31;i>=0;i--)
        {
            int b=(x>>i)&1;
            if(!tire[p][b]) tire[p][b]=++tot,tire[tot][1]=0,tire[tot][0]=0;
            p=tire[p][b];
        }
    }
    
    int Search(int x)
    {
        int p=1,y=0;
        for(int i=31;i>=0;i--)
        {
            int b=!((x>>i)&1);
            if(tire[p][b]) y+=b<<i,p=tire[p][b];
            else y+=(!b)<<i,p=tire[p][!b];
        }
        return x^y;
    }
    
    void connect(int u,int v,int e)
    {
        edge[++cnt].v=v;edge[cnt].e=e;
        edge[cnt].nxt=head[u];head[u]=cnt;
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            tot=1;
            tire[1][0]=0,tire[1][1]=0;
            memset(head,0,sizeof(head));
            cnt=0;
            for(int i=1,u,v,e;i<n;i++)
            {
                scanf("%d%d%d",&u,&v,&e);
                connect(u,v,e);
                connect(v,u,e);
            }
            Dfs(0,0);
            int ans=-1;
            for(int i=0;i<n;i++)
            {
                Insert(d[i]);
                ans=max(ans,Search(d[i]));
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    python安装pip
    MySQL免安装版
    git仓库删除所有提交历史记录,成为一个干净的新仓库
    git地址带上密码,不用每次提交都输入密码
    virtualenv
    mac卸载python
    换源
    屏幕旋转,ViewController触发事件
    ViewController启动加载过程
    使用 symbolicatecrash转化crash日志
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11313489.html
Copyright © 2020-2023  润新知