P4551 最长异或路径

题目来自洛谷网站:

思路:

代码:

cpp 复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100010;

int n;
//存树
typedef pair<int, int> PII;
vector<PII> t[N];
//记录这个点到根节点的异或和
int ls[N];
//01字典树
int ch[N*31][2], idx;

//找到每个点到起点这一段的异或和
void dfs(int u, int father){
    for(auto [v, w]: t[u]){
        //判断子节点是不是父亲节点
        if(v == father) continue;
        //该点到起点 异或和
        ls[v] = ls[u] ^ w;
        dfs(v, u);
    }
}


void insert(int x){
    int p = 0;
    for(int i = 30; i >= 0; i--){
        int j = x >> i & 1;
        if(!ch[p][j]) ch[p][j] = ++idx;
        p = ch[p][j];
    }
}

//在树中查找1个节点和另1个节点的异或最大值
//返回的结果
int query(int x){
    int res = 0, p =0;
    for(int i = 30; i >= 0; i--){
        int j = x >> i & 1;
        if(ch[p][!j]){
            res += 1 << i;
            p = ch[p][!j];
        }
        else p = ch[p][j];
    }
    return res;
}

signed main(){
    cin >> n;
    for(int i = 1; i < n; i++){
        int x, y, z; cin >> x >> y >> z;
        //无向边
        t[x].push_back({y,z});
        t[y].push_back({x,z});
    }
    //找到每个点到起点这一段的异或和
    //节点从1开始的
    dfs(1,0);
    
    //将各点到起点的异或和 存到01字典树中
    for(int i = 1;i <= n; i++) insert(ls[i]);
    
    //枚举一个节点,在找到这个节点和树中一个节点异或的最大值
    int ans = 0;
    for(int i = 1; i <= n; i++){
        ans = max(ans, query(ls[i]));
    }
    
    cout << ans << endl;
    return 0;
}
相关推荐
陆嵩4 分钟前
从一个小例子实践代数多重网格方法
算法·amg·多重网格·粗化·插值算子·光滑·v cycle
清水白石00810 分钟前
模板方法模式全解析:用抽象基类定义算法骨架,让子类优雅填充细节
数据库·python·算法·模板方法模式
DeepModel11 分钟前
【分类算法】C4.5分类算法超详细讲解
算法·决策树·回归
努力学算法的蒟蒻14 分钟前
day96(2.25)——leetcode面试经典150
算法·leetcode·面试
吕司16 分钟前
LeetCode Hot Code——找到字符串中所有字母异位词
算法·leetcode
AI科技星20 分钟前
物理世界的几何建构:论统一场论的本体论革命与概念生成
人工智能·opencv·线性代数·算法·矩阵
让我上个超影吧22 分钟前
【力扣34】在排序数组中查找元素的第一个和最后一个位置
java·数据结构·算法·leetcode
zaiyang遇见25 分钟前
[GESP202509 六级] 货物运输
深度优先·贪心·树的遍历·gesp六级·树的存储
数据知道26 分钟前
MongoDB 数值更新原子操作:`$inc` 实现点赞、计数器等高并发原子操作
数据库·算法·mongodb
逆境不可逃33 分钟前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式