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

    题目链接:poj 3764 The xor-longest Path

    题目大意:给定一棵树,每条边上有一个权值。找出一条路径,使得路径上权值的亦或和最大。

    解题思路:dfs一遍,预处理出每一个节点到根节点路径的亦或和rec,那么随意路径均能够表示rec[a] ^ rec[b],所以问题

    就转换成在一些数中选出两个数亦或和最大。那么就建立字典树查询就可以。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 100005 * 32;
    const int sigma_size = 2;
    
    struct Tire {
        int sz;
        int g[maxn][sigma_size];
    
        void init();
        int idx(char ch);
        void insert(int s);
        int find(int s);
    }T;
    
    int N, M, E, first[maxn], jump[maxn], link[maxn], val[maxn], rec[maxn];
    
    inline void add_Edge (int u, int v, int w) {
        link[E] = v;
        val[E] = w;
        jump[E] = first[u];
        first[u] = E++;
    }
    
    void dfs (int u, int pre, int s) {
        T.insert(s);
        rec[M++] = s;
        for (int i = first[u]; i + 1; i = jump[i]) {
            int v = link[i];
            if (v == pre)
                continue;
            dfs(v, u, s ^ val[i]);
        }
    }
    
    int main () {
        while (scanf("%d", &N) == 1) {
            M = E = 0;
            T.init();
            memset(first, -1, sizeof(first));
    
            int u, v, w;
            for (int i = 1; i < N; i++) {
                scanf("%d%d%d", &u, &v, &w);
                add_Edge(u, v, w);
                add_Edge(v, u, w);
            }
            dfs(0, 0, 0);
    
            int ans = 0;
            for (int i = 0; i < M; i++)
                ans = max(ans, T.find(rec[i]));
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    void Tire::init() {
        sz = 1;
        memset(g[0], 0, sizeof(g[0]));
    }
    
    int Tire::find(int s) {
        int ret = 0, u = 0;
        for (int i = 30; i >= 0; i--) {
            int v = ((s>>i)&1) ^ 1;
    
            if (g[u][v])
                ret |= (1<<i);
            else
                v = v^1;
            u = g[u][v];
        }
        return ret;
    }
    
    void Tire::insert(int s) {
        int u = 0;
    
        for (int i = 30; i >= 0; i--) {
            int v = (s>>i)&1;
    
            if (g[u][v] == 0) {
                memset(g[sz], 0, sizeof(g[sz]));
                g[u][v] = sz++;
            }
            u = g[u][v];
        }
    }
  • 相关阅读:
    警示
    【拒绝挂分】盘点蒟蒻ghy的各种sb错误
    牛客NOIPtg day5 B-demo的gcd
    数字校园APP——视频分享
    数字校园APP——软件需求规格说明书
    数字校园APP——可行性报告分析
    数字校园APP开发与应用
    结对编程第二次作业——四则运算自动生成器
    软件工程第四次作业
    软件工程第三次作业
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5150805.html
Copyright © 2011-2022 走看看