【POJ 3764】 The xor-longest path

【题目链接】

            http://poj.org/problem?id=3764

【算法】

           首先,我们用Si表示从节点i到根的路径边权异或和

           那么,根据异或的性质,我们知道节点u和节点v路径上的边权异或和就是Sx xor Sy

           问题就转化为了 : 在若干个数中,找到两个数异或的最大值,可以用Trie树加速,具体细节笔者不再赘述

【代码】

           

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <stack>
#include <limits.h>
using namespace std;
#define MAXN 200010
 
int i,n,tot,u,v;
int head[MAXN];
long long s[MAXN];
long long w,ans;

struct Edge
{
    int to;
    long long w;
    int nxt;
} e[MAXN<<1];

inline void add(int u,int v,long long w)
{
    tot++;
    e[tot] = (Edge){v,w,head[u]};
    head[u] = tot;
}
inline void dfs(int u,int fa)
{
    int i,v;
    long long w;
    for (i = head[u]; i; i = e[i].nxt)
    {
        v = e[i].to;
        w = e[i].w;
        if (v == fa) continue;
        s[v] = s[u] ^ w;
        dfs(v,u);    
    }    
}
class Trie
{
    private :
        int tot;
        int child[MAXN*31][2];
    public :
        inline void clear()
        {
            tot = 0;
            memset(child,0,sizeof(child));
        }
        inline void insert(long long x)
        {
            int i,t,now = 0;
            for (i = 0; i < 31; i++)
            {
                if (x & (1 << (30- i))) t = 1;
                else t = 0; 
                if (!child[now][t]) child[now][t] = ++tot;
                now = child[now][t];    
            } 
        }
        inline long long getans(long long x)
        {
            int i,now = 0,t;
            long long ans = 0,val;
            for (i = 0; i < 31; i++)
            {
                if (x & (1 << (30 - i))) t = 1;
                else t = 0;
                val = 1 << (30 - i);
                if (child[now][t^1]) 
                {
                    now = child[now][t^1];
                    ans |= val;
                } else now = child[now][t];
            }
            return ans;
        } 
} T;

int main()
{
    
    while (scanf("%d",&n) != EOF)
    {
        T.clear();
        tot = 0; ans = 0;
        for (i = 0; i < n; i++) head[i] = 0;    
        for (i = 1; i < n; i++)
        {
            scanf("%d%d%lld",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        dfs(0,-1);
        for (i = 0; i < n; i++) T.insert(s[i]);
        for (i = 0; i < n; i++) ans = max(ans,T.getans(s[i])); 
        printf("%lld\n",ans);
    }
    
    return 0;    
} 

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9250966.html