zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    BootstrapBlazor 组件库介绍
    BootstrapBlazor 组件库使用体验---Table篇
    【转载】Bootstrap Blazor 组件介绍 Table (一)自动生成列功能介绍
    【转载】Bootstrap Blazor 组件介绍 Table (二)自定义模板列功能介绍
    【转载】Bootstrap Blazor 组件介绍 Table (三)列数据格式功能介绍
    使用acme.sh从Let's Encrypt申请SSL证书
    Docker一些基本操作
    Nginx配置https以及配置说明
    vi操作
    CentOS 7下安装Docker
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11313489.html
Copyright © 2011-2022 走看看