zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x16Trie POJ3764异或最大路径

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

    我们可以在O(32*n)时间内求出一个长度为n的序列中取两个数的最大异或,而树中的异或有如下公式:path[x]=path(root,x) xor path(root,y),所以处理出path(root,i)之后就简化成了

    简单问题,处理方式是dfs,有公式:path[x]=path(x->father,x) xor path(root,x->father).

    注意边是无方向的,数组大小开合适。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<string.h>
    using namespace std;
    #define maxn 100010
    int trie[maxn*33][2],head[maxn],e[maxn*2],len[maxn*2],nxt[maxn*2];
    int num=0,tot=0,n;//e中保存的是边的右端点 num为边的编号 
    int d[maxn];//根节点到i点的异或和
    bool v[maxn]; 
    void addedge(int u,int v,int w){
        e[++num]=v;
        len[num]=w;
        nxt[num]=head[u];
        head[u]=num;
    }
    void dfs(int x){
        for(int i=head[x];i;i=nxt[i]){
            int to=e[i],weight=len[i];
            if(v[to])continue;
            v[to]=true;
            d[to]=d[x]^weight;//有公式:d[x]=d[x->father] xor x->weight
            dfs(to); 
        }
    }
    void insert(int x){
        int p=0;
        for(int i=31;i>=0;i--){
            int tmp=(x>>i)&1;
            if(!trie[p][tmp])trie[p][tmp]=++tot;
            p=trie[p][tmp];
        }
    }
    int search(int x){
        int ans=0,p=0;
        for(int i=31;i>=0;i--){
            int tmp=(x>>i)&1;
            if(trie[p][tmp^1]){
                ans=(ans<<1)+(tmp^1);
                p=trie[p][tmp^1];
            }else{
                ans=(ans<<1)+tmp;
                p=trie[p][tmp];
            }
        }
        return ans;
    }
    void xor_max(){
        memset(d,0,sizeof(d));
        memset(trie,0,sizeof(trie));
        memset(head,0,sizeof(head));
        memset(nxt,0,sizeof(nxt));
        memset(v,0,sizeof(v));
        num=0;
        v[0]=1;
        tot=0;
        for(int i=0;i<n-1;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        dfs(0);
        int ans=0;
        for(int i=0;i<n;i++){
            insert(d[i]);
            if(i){
                ans=max(ans,d[i]^search(d[i]));
            }        
        }
        cout<<ans<<endl; 
    }
    int main(){
        while(cin>>n){
            xor_max();
        } 
        return 0;
    } 
  • 相关阅读:
    HTML DOM 节点
    HTML DOM 简介
    XML DOM
    JavaScript Window Screen
    JavaScript Window
    JavaScript Date(日期) 对象
    11.2 正睿停课训练 Day15
    10.31 正睿停课训练 Day13
    10.29 正睿停课训练 Day11
    BZOJ.4361.isn(DP 树状数组 容斥)
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13156123.html
Copyright © 2011-2022 走看看