码迷,mamicode.com
首页 > 其他好文 > 详细

「POJ 3764」The xor-longest Path

时间:2020-02-04 20:45:33      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:register   ref   mem   二进制   sdi   website   gis   space   输入格式   

给定一棵 N 个节点的树,树上的每条边都有一个权值。从数中选择两个点 x 和 y ,把从 x 到 y 路径上的所有边权 xor 起来,得到的结果最大是多少?

POJ3764

分析

显然, \(d[u]=d[fa_u] \ xor \ w_{u,fa_u}\) ,于是我们可以通过一遍 bfs 来求出每个节点到根节点的 d[i] 。

然后问题转化为求出最大的 \(d[u] \ xor \ d[v]\)

根据 xor 运算的性质:相同为 0 ,不同为 1 。我们可以用一棵 trie 树将 d[i] 的二进制位储存下来,并贪心的在 trie 树中寻找与当前位的数值相反的数,如果有,则跳到相反数中;如果没有,则跳到相同的数中,然后求出寻找过程中得到二进制数与当前数的 xor 值,最后取 max 就好了。

一些废话:这道题改了我半天,然后又对着标程改,发现没毛病......只是这个标程有点烦,是用的多组测试数据的输入格式,在 WA 了 INF 遍后,重新看题,发现题目就是多组测试数据......怎么就不给一个多组测试数据的样例呢......

代码

//=========================
//  author:tyqs
//  date:2019.12.7
//  website:http://tyqs.kim
//=========================
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100003
#define il inline
#define re register
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
typedef long long ll;

template <typename T> inline void read(T &x) {
    T f = 1; x = 0; char c;
    for (c = getchar(); !isdigit(c); c = getchar()) if (c == '-') f = -1;
    for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    x *= f;
}

struct edge {
    int to, nxt, val;
} e[N<<1];

int n, ans;
int head[N<<1], cnt, d[N];
int trie[N*32][2], tot;

void dfs(int u, int fa) {
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to, w = e[i].val;
        if (v == fa) continue;
        d[v] = d[u] ^ w;
        dfs(v, u);
    }
}

void insert(int u, int v, int w) {
    e[++cnt] = (edge){v, head[u], w};
    head[u] = cnt;
}

void insert_trie(int x) {
    int p = 1;
    for (int i = 30; i >= 0; --i) {
        int c = x >> i & 1;
        if (!trie[p][c]) trie[p][c] = ++tot;
        p = trie[p][c];
    }
}

int search(int x) {
    int p = 1, ret = 0;
    for (int i = 30; i >= 0; --i) {
        int c = x >> i & 1;
        if (!trie[p][c^1]) p = trie[p][c];
        else ret |= (1 << i), p = trie[p][c^1];
    }
    return ret;
}

int main() {
    int u, v, w;
    while (~scanf("%d", &n)) {
        memset(head, 0, sizeof head);
        memset(d, 0, sizeof d);
        memset(trie, 0, sizeof trie);
        cnt = ans = 0; tot = 1;
        for (int i = 1; i < n; ++i) {
            read(u), read(v), read(w);
            insert(u, v, w), insert(v, u, w);
        }
        dfs(u, -1);
        tot = 1;
        for (int i = 0; i < n; ++i) {
            insert_trie(d[i]);
            ans = max(ans, search(d[i]));
        }
        printf("%d\n", ans);
    }
    return 0;
}

「POJ 3764」The xor-longest Path

标签:register   ref   mem   二进制   sdi   website   gis   space   输入格式   

原文地址:https://www.cnblogs.com/hlw1/p/12260610.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!