zoukankan      html  css  js  c++  java
  • POJ3764 The xor-longest Path(字典树)

    题意

    给你一棵树,n个节点,n-1条边每条边i都有一个权值wi。定义任意两点间的权值为:这两点间的路径上的所有边的值的异或。比如a点和b点间有i,j,k三条边,那么ab两点间的权值为:wi^wj^wk。求这个最大的权值(最长异或路径)。

    (n<=105)

    题解

    首先  边权可以放到点权上

    然后我们可以搞一个树上的前缀异或和.
    这样的话 把当前点的所有点权加到trie树里
    从最高位到最低位走不同的路
    例:1011100101
    我们要走:0100011010
    如果走不了就顺着走
    跑出来的数异或当前的数就是经过这个点的最优解了

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const long long N=201000;
     8 long long ans,tot,cnt,head[N],n,mx,flag;
     9 struct edge{
    10     long long to,nxt,w;
    11 }e[N*2];
    12 struct tree{
    13     long long nxt[4];
    14 }tr[N*50];
    15 void insert(long long a){
    16     long long now=0,z;
    17     for(long long i=31;i>=1;i--){
    18         if(a&(1<<(i-1)))z=1;
    19         else z=0;
    20         if(!tr[now].nxt[z]){
    21             tr[now].nxt[z]=++tot;
    22             memset(tr[tot].nxt,0,sizeof(tr[tot].nxt));
    23         }
    24         now=tr[now].nxt[z];
    25     }
    26 }
    27 void check(long long x){
    28     long long tmp=0;
    29     long long now=0,z;
    30     for(long long i=31;i>=1;i--){
    31         if(x&(1<<(i-1)))z=1;
    32         else z=0;
    33         if(tr[now].nxt[!z]){
    34             tmp=(tmp<<1)+1;
    35             now=tr[now].nxt[!z];
    36         }
    37         else{
    38             tmp=tmp<<1;
    39             now=tr[now].nxt[z];
    40         }
    41     }
    42     ans=max(ans,tmp);
    43 }
    44 void add(long long u,long long v,long long w){
    45     cnt++;
    46     e[cnt].nxt=head[u];
    47     e[cnt].to=v;
    48     e[cnt].w=w;
    49     head[u]=cnt;
    50 }
    51 void dfs1(long long u,long long f,long long w){
    52     insert(w);
    53     for(long long i=head[u];i;i=e[i].nxt){
    54         long long v=e[i].to;
    55         if(v==f)continue;
    56         w^=e[i].w;
    57         dfs1(v,u,w);
    58         w^=e[i].w;
    59     }
    60 }
    61 void dfs2(long long u,long long f,long long w){
    62     check(w);
    63     for(long long i=head[u];i;i=e[i].nxt){
    64         long long v=e[i].to;
    65         if(v==f)continue;
    66         w^=e[i].w;
    67         dfs2(v,u,w);
    68         w^=e[i].w;
    69     }
    70 }
    71 int main(){
    72     while(~scanf("%lld",&n)){
    73         ans=0;cnt=0;tot=0;mx=0;flag=0;
    74         memset(head,0,sizeof(head));
    75         memset(tr[0].nxt,0,sizeof(tr[0].nxt));
    76         for(long long i=1;i<=n-1;i++){
    77             long long u,v,w;
    78             scanf("%lld%lld%lld",&u,&v,&w);
    79             u++;v++;
    80             add(u,v,w);
    81             add(v,u,w);
    82         }
    83         insert(0);
    84         dfs1(1,0,0);
    85         dfs2(1,0,0);
    86         printf("%lld
    ",ans);
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    eclipse如何正确部署tomcat7
    调用awk的三种方式
    jupyter的简单操作
    编程语言简介
    2019.9.6作业
    计算机的基本组成
    9.2作业
    CPP 栈 示例
    关于使用栈将一般运算式翻译为后缀表达式并实现三级运算的方法及实例(cpp版)
    深度遍历破解数独游戏
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9559154.html
Copyright © 2011-2022 走看看