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

最长异或路径 - Trie

时间:2020-06-14 12:57:13      阅读:60      评论:0      收藏:0      [点我收藏+]

标签:void   define   int   names   script   fir   else   return   class   

Description

给定一棵 n 个点的带权树,结点下标从 1开始到 N。寻找树中找两个结点,求权值最大的异或路径。异或路径指的是指两个结点之间唯一路径上的所有边权的异或。

Solution

随意定根,算出根到所有点的异或和,然后转化为最大异或点对问题

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;

int n,t1,t2,t3,a[N],vis[N];
vector <pair<int,int> > g[N];

void dfs(int p) {
    vis[p]=1;
    for(pair<int,int> pr:g[p]) {
        int q=pr.first, w=pr.second;
        if(vis[q]==0) {
            a[q]=a[p]^w;
            dfs(q);
        }
    }
}

namespace trie {
    int ch[N][2],ind;
    void insert(int x) {
        int p=0;
        for(int i=31;i>=0;--i) {
            int u=(x>>i)&1;
            if(ch[p][u]==0) {
                ch[p][u]=++ind;
            }
            p=ch[p][u];
        }
    }
    int query(int x) {
        int p=0,ans=0;
        for(int i=31;i>=0;--i) {
            int u=(x>>i)&1;
            u^=1;
            if(ch[p][u]) {
                ans|=1<<i;
                p=ch[p][u];
            }
            else {
                p=ch[p][u^1];
            }
        }
        return ans;
    }
}

using trie::insert;
using trie::query;

signed main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<n;i++) {
        cin>>t1>>t2>>t3;
        g[t1].push_back({t2,t3});
        g[t2].push_back({t1,t3});
    }
    dfs(1);
    for(int i=1;i<=n;i++) {
        insert(a[i]);
    }
    int ans=0;
    for(int i=1;i<=n;i++) {
        ans=max(ans,query(a[i]));
    }
    cout<<ans;
}

最长异或路径 - Trie

标签:void   define   int   names   script   fir   else   return   class   

原文地址:https://www.cnblogs.com/mollnn/p/13124174.html

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