[P4551] 最长异或路径 题解

过程

手写利用DFS求出每个点到根节点的异或距离
不难得出
xor_dis[x][y]=xor_dis[0][x]^xor_dis[0][y]

于是树上异或问题转换成了Trie上异或问题。

代码

直接看代码吧,注释很全

#include <iostream>
#include <cstdio>
using namespace std;


const int N=1e6+128;
namespace G
{
    struct Edge
    {
        int to;
        int next;
        unsigned int val;
    }   egde[N];
    int deg=0;

    int head[N];

    inline void add_edge(int from,int to,unsigned  int val)
    {
        egde[++deg].next=head[from];
        egde[deg].to=to;
        egde[deg].val=val;

        head[from]=deg;
    }

    unsigned int dis[N];    // 用来表示 1 节点到 n 节点 xor路径

    void dfs(int x,unsigned int val)
    {
        dis[x]=val;
        for(int i=head[x]; i!=0; i=egde[i].next)
            dfs(egde[i].to,val^egde[i].val);
    }
}


namespace trie
{
    struct Node
    {
        Node * next[2];
    }   trie[N];
    int m;

    inline Node * NEW()
    {
        return &trie[m++];
    }

    inline int getbit(unsigned int val,int addr)
    {
        return (val>>(addr-1))&1;
    }

    void insert(unsigned int val,int n,Node * trie_node)
    {
        if(n==0)
            return ;
        int c=getbit(val,n);
        if(trie_node->next[c]==NULL)
            trie_node->next[c]=NEW();
        insert(val,n-1,trie_node->next[c]);
    }

    void FindMaxVal(unsigned int &buffer_num,int n,Node * trie_node)
    {
        if(n==0)
            return ;
        int c=getbit(buffer_num,n);
        if(trie_node->next[c^1]!=NULL) //c^1 该位为1
        {
            buffer_num|=1<<(n-1);
            FindMaxVal(buffer_num,n-1,trie_node->next[c^1]);
        }   else    {   //  为 0
            buffer_num^=c<<(n-1);   //c=c^c==0
            FindMaxVal(buffer_num,n-1,trie_node->next[c]);
        }
    }

}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<n; i++) //n个点只有 n-1条边
    {
        int u,v;
        unsigned w;
        scanf(" %d %d %u",&u,&v,&w);
        G::add_edge(u,v,w);
    }
    G::dfs(1,0);

    trie::NEW();

    for(int i=1;i<=n;i++)
        trie::insert(G::dis[i],32,&trie::trie[0]);

    unsigned int maxn=0;

    //这里有个重要结论 xor_dis[x][y]=xor_dis[0][x]^xor_dis[0][y];

    for(int i=1;i<=n;i++)
    {
        unsigned int t=G::dis[i];
        trie::FindMaxVal(t,32,&trie::trie[0]);
        maxn=max(maxn,t);
    }

    printf("%u",maxn);
}
posted @ 2021-10-22 09:30  Icys  阅读(45)  评论(0编辑  收藏  举报