POJ-3764 The xor-longest Path 【思维 + 01字典树】

传送门
题意: 给定一棵带权树,求树上一条简单路径,经过的边异或值最大.

思路:任意一条u-> v的路径f(u, v) = f(1, u) ^ f(1, v), 所以我们可以把从1出发到某个点的异或值全部算出来,然后问题就变成了从这些值中选择两个数异或最大,那么就是01字典树的问题了,所以就解决了. 还是注意字典树内存问题
AC Code

const int maxn = 1e5 + 5;
const int maxm = 2e6 + 5;
const int siz = 33;
struct Trie {
    int num, val, nex[2];
}trie[maxm];
int idx, n;
void build(int n) {
    bitset<siz>bit(n);
    int x = 0;
    for(int i = 31 ; i >= 0 ; i --) {
        int k = bit[i];
        if(!trie[x].nex[k])
            trie[x].nex[k] = ++idx;
        x = trie[x].nex[k];
        trie[x].num++; // 表示这条路存在.
    }
    trie[x].val = n;   //把路的终点设置成该条路是那个数的.
}
int query(int n) {
    bitset<siz>bit(n);
    int x = 0;
    for(int i = 31 ; i >= 0 ; i --) {
        int k = bit[i];
        if(trie[trie[x].nex[k^1]].num)   //如果有相反的点可以走就走相反的.
            x = trie[x].nex[k^1];
        else x = trie[x].nex[k]; // 否则只能继续往前走, 并且这边一定是有路的, 只要保证是有数可以匹配的..
    }
    return trie[x].val;   //返回走的那条路的终点的值.
}
struct node {
    int to, next, w;
}e[maxn<<1];
int cnt, head[maxn];
void init() {
    cnt = idx = 0; Fill(head, -1);
    Fill(trie, 0);
}
void add(int u, int v, int w) {
    e[cnt] = node{v, head[u], w};
    head[u] = cnt++;
}
int a[maxn];
void dfs(int u, int fa, int len) {
    build(len); a[u] = len;
    for (int i = head[u] ; ~i ; i = e[i].next) {
        int to = e[i].to;
        if (fa == to) continue;
        dfs(to, u, e[i].w^len);
    }
}
void solve() {
    while(~scanf("%d", &n)) { init();
        for (int i = 1 ; i < n ; i ++) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            ++ u; ++ v;
            add(u, v, w); add(v, u, w);
        }
        dfs(1, -1, 0);
        int ans = 0;
        for (int i = 1 ; i <= n ; i ++) {
            ans = max(ans, a[i]^query(a[i]));
        }
        printf("%d\n", ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值