A
B

P4551 最长异或路径 The XOR-longest Path 题解

The XOR-longest Path

不好的阅读体验

Description

原题来自:POJ 3764

给定一棵 n 个点的带权树,求树上最长的异或和路径。

Input Format

第一行一个整数 n,接下来 n−1 行每行三个整数 u,v,w,表示 u,v 之间有一条长度为 w 的边。

Output Format

输出一行一个整数,表示答案。

Sample

样例输入

4
1 2 3
2 3 4
2 4 6

样例输出

7

样例解释

最长的异或和路径是 1→2→3
它的长度是

3⨁4=7。

注意:结点下标从 1 开始到 N。

注:x⨁y 表示 x 与 y 按位异或。

Hint

对于 100% 的数据,1 ≤ n ≤ 10^5 , 1 ≤ u,v ≤ n , 0 ≤ w ≤ 2^31;

---------------------------优雅的分界线----------------------------

正片开始

首先首当其冲先想到的是暴力,即两遍dfs跑图,第一遍预处理,第二遍求根到深度最大的叶子节点所有边的异或,求出答案

然而当我们把暴力代码交上去的时候,迎接我们的不是T,而是WA......

为什么会WA呢?

我们再仔细地读一遍题—————— 树上最长的异或和路径

哎呀!

不是从根到叶子节点的最长路,而是最长的异或和路径;

最近犯唐诗真是越来越严重了呀

所以我们考虑 dijk Tire树。

仔细一想,这不就是0-1 Tire树嘛

只要将每个点到根的异或距离预处理一下,然后都存到0-1树里,就跟 P10471 最大异或对 The XOR Largest Pair (0-1树的板子题)一样了啊

然后只要求其中的最大值就行了

最后,代码附上,完结撒花

#include<bits/stdc++.h>
#define int long long
#define Blue_Archive return 0
#define rint register int
using namespace std;
const int N = 5000010;
const int p = 1313131;
const int mod = 1e9 + 7;

int n;
int ans;
int val[N];
int cnt;
int son[N][2];//0-1 trie树
int to[N];//前向星
int nxt[N];//前向星
int h[N];//前向星
int w[N];//前向星
int tot = -1;//前向星

inline int max(int x,int y)
{
	return x > y ? x : y;
}

inline int min(int x,int y)
{
	return x < y ? x : y; 
}

inline void add(int u,int v,int ww)
{
    nxt[++ tot] = h[u];
    to[tot] = v;
    w[tot] = ww;
    h[u] = tot;
}

inline void update(int val,int x)
{
    for(int i = (1 << 30);i;i >>= 1)
    {
        bool t = i & val;
        if(!son[x][t]) son[x][t] = ++ cnt;
        x = son[x][t];
    }
}

inline int Shiroko(int val,int x)
{
    int ans = 0;
    for(int i = (1 << 30);i;i >>= 1)
    {
        bool t = i & val;
        if(!son[x][!t]) 
        {
            x = son[x][t];
        }
        else
        {
            x = son[x][!t];
            ans += i;
        }
    }
    return ans;
}

inline void Hoshino(int x,int f)
{
    for(int i = h[x];~i;i = nxt[i])
    {
        int v = to[i];
        if(v == f) continue;
        val[v] = val[x] ^ w[i];
        Hoshino(v,x);
    }
}

// inline void hifumi(int x,int dp)
// {
//     if(dp > 1) ans ^= val[x];
//     else ans = val[x];
//     if(fa[x]) hifumi(fa[x],dp + 1);
//     else return;
// }

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    memset(h,-1,sizeof(h));
    cin >> n;
    // cnt = 1;
    for(int i = 1,u,v,ww;i < n;i ++)
    {
        cin >> u >> v >> ww;
        add(u,v,ww);
        add(v,u,ww);
    }
    Hoshino(1,-1);
    for(int i = 1;i <= n;i ++)
    {
        update(val[i],0);
    }
    ans = 0;
    for(int i = 1;i <= n;i ++)
    {
        ans = max(ans,Shiroko(val[i],0));
    }
    cout << ans << "\n";
    Blue_Archive;
}
/////////////////////////////
//         Shiroko         //
/////////////////////////////
posted @ 2025-07-31 06:44  MyShiroko  阅读(18)  评论(0)    收藏  举报