zoukankan      html  css  js  c++  java
  • Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值

    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 5646   Accepted: 1226

    Description

    In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:

    _{xor}length(p)=oplus_{e in p}w(e)

    ⊕ is the xor operator.

    We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?  

    Input

    The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.

    Output

    For each test case output the xor-length of the xor-longest path.

    Sample Input

    4
    0 1 3
    1 2 4
    1 3 6
    

    Sample Output

    7

    Hint

    The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)

    题意:给出一颗n个节点的边权树,求一条路径(u,v),使得路径上的边的权值异或值最大

    思路:我们可以先0为根,求出其他节点i到根的路径的边权异或值d[i],对于u,v之间路径的边权异或结果就是d[u]^d[v], 那么问题转化为给出n个数,求任意两个异或的最大值

    把每一个数以二进制形式从高位到低位插入trie中,然后依次枚举每个数,在trie中贪心,即当前为0则向1走,为1则向0走。

    一开始写动态分配节点的trie一直tle。。。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const int N = 100005;
    
    int n;
    struct Edge {
        int v, w, nex;
        Edge() {}
        Edge(int v, int w, int nex) : v(v), w(w), nex(nex) {}
    };
    Edge e[N << 1];
    int head[N], tot;
    void add(int u, int v, int w) {
        e[tot] = Edge(v, w, head[u]);
        head[u] = tot++;
    }
    void read() {
        memset(head, -1, sizeof head);
        tot = 0;
        int u, v, w;
        for(int i = 1; i < n; ++i) {
            scanf("%d%d%d", &u, &v, &w);
            add(u, v, w);
            add(v, u, w);
        }
    }
    int d[N], vis[N];
    void bfs() {
        queue<int> que;
        que.push(0);
        d[0] = 0;
        memset(vis, 0, sizeof vis);
        int u, v, w;
        vis[0] = 1;
        while(!que.empty()) {
            u = que.front(); que.pop();
            for(int i = head[u]; ~i; i = e[i].nex) {
                v = e[i].v; w = e[i].w;
                if(vis[v]) continue;
                d[v] = d[u] ^ w;
                vis[v] = 1;
                que.push(v);
            }
        }
    }
    int ch[N * 32][2];
    struct Trie {
        int sz;
        Trie() { sz = 1; memset(ch[0], 0, sizeof ch[0]); }
        void _insert(int bs[]) {
            int u = 0;
            for(int i = 30; i >= 0; --i) {
                int c = bs[i];
                if(!ch[u][c]) {
                    memset(ch[sz], 0, sizeof ch[sz]);
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
        }
        int _search(int bs[]) {
            int u = 0, ans = 0;
            for(int i = 30; i >= 0; --i) {
                int c = bs[i];
                if(c == 1) {
                    if(ch[u][0]) { ans += (1 << (i)); u = ch[u][0]; }
                    else u = ch[u][1];
                }else {
                    if(ch[u][1]) { ans += (1 << (i)); u = ch[u][1]; }
                    else u = ch[u][0];
                }
            }
            return ans;
        }
    };
    
    int ans;
    int b[35];
    void get(int x) {
        int ls = 0;
        memset(b, 0, sizeof b);
        while(x) {
            b[ls++] = x % 2;
            x >>= 1;
        }
    }
    void solve() {
        Trie mytrie;
        ans = 0;
        for(int i = 0; i < n; ++i) {
            get(d[i]);
            mytrie._insert(b);
            ans = max(ans, mytrie._search(b));
        }
        printf("%d
    ", ans);
    }
    int main() {
       // freopen("in.txt", "r", stdin);
        while(~scanf("%d", &n)) {
            read();
            bfs();
            solve();
        }
    }
    View Code
  • 相关阅读:
    《Think in Java》(十四)类型信息
    《Think in Java》(十三)字符串
    《Think in Java》(十二)通过异常处理错误
    《Think in Java》(十七)容器深入研究
    《Think in Java》(十一)持有对象
    集合框架概览
    Gulp 自动化构建过程
    自动化打包 CSS
    更新 Node 稳定版本命令
    mac 命令行打开vscode
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/5507536.html
Copyright © 2011-2022 走看看