AcWing 144 最长异或值路径(贪心,trie)

题目链接

解题思路

  以任意一个点为根,求出它到根的异或值,那么两个点之间异或值就是两者到根的异或值的异或值(因为重复的数异或值等于0),然后就变成了求n个数中两个数最大的异或值

代码

const int maxn = 1e6+10;
const int maxm = 3e6+10;
vector<P> e[maxn];
ll d[maxn];
int trie[maxm][2], tot;
void insert(int num) {
    int p = 0;
    for (int i = 30; i>=0; --i) {
        auto &x = trie[p][num>>i&1];
        if (!x) x = ++tot;
        p = x;
    }
}
void dfs(int u, int p) {
    for (auto v : e[u])
        if (v.second!=p) {
            insert(d[v.second]=d[u]^v.first);
            dfs(v.second,u);
        }
}
ll solve(int num) {
    int p = 0; ll res = 0;
    for (int i = 30; i>=0; --i) {
        res <<= 1;
        int x = num>>i&1;
        if (trie[p][x^1]) {
            res |= 1;
            p = trie[p][x^1];
        }
        else p = trie[p][x];
    }
    return res;
}
int main() {
    int n; scanf("%d",&n);
    for (int i = 0; i<n; ++i) {
        int u,v,w; scanf("%d%d%d",&u,&v,&w);
        e[u].push_back({w,v});
        e[v].push_back({w,u});
    }
    dfs(0,-1);
    ll res = 0;
    for (int i = 0; i<n; ++i) res = max(res,solve(d[i]));
    printf("%lld\n",res);
    return 0;
}
posted @ 2020-07-19 17:01  shuitiangong  阅读(140)  评论(0编辑  收藏  举报