poj - 3764 - The xor-longest Path(Trie)

题意:一棵 n 个结点的树,树边有权值w(0 <= w < 2^31),求最两结点间的最大异或。

题目链接:http://poj.org/problem?id=3764

——>>取0为根,预处理出所有结点到根的异或xOr[i]。那么结点 a 与结点 b 之间的路径异或就是xOr[a] ^ xOr[b]。。

权值 w 最多31位,于是,将每个xOr的二进制表示从高位到低位插入到 01 Trie中(0为0,非0为1)。。

查询时从高位开始贪心。。

很好的题目,第一次不在字母上使用Trie。。

#include <cstdio>
#include <cstring>
#include <algorithm>

using std::max;

const int MAXN = 100000 + 10;
const int MAX_NODE = 3000000 + 10;
const int MAX_X = 2;
const int MAX_BIT = 30;

struct EDGE
{
    int to;
    int w;
    int nxt;
} edge[MAXN << 1];

int n;
int hed[MAXN], ecnt;
int xOr[MAXN];
int ch[MAX_NODE][MAX_X], sz;

void Init()
{
    ecnt = 0;
    memset(hed, -1, sizeof(hed));
    xOr[0] = 0;
    sz = 1;
    memset(ch[0], 0, sizeof(ch[0]));
}

void AddEdge(int u, int v, int w)
{
    edge[ecnt].to = v;
    edge[ecnt].w = w;
    edge[ecnt].nxt = hed[u];
    hed[u] = ecnt++;
}

void Read()
{
    int u, v, w;

    for (int i = 0; i < n - 1; ++i)
    {
        scanf("%d%d%d", &u, &v, &w);
        AddEdge(u, v, w);
        AddEdge(v, u, w);
    }
}

void Dfs(int u, int fa)
{
    for (int e = hed[u]; e != -1; e = edge[e].nxt)
    {
        int v = edge[e].to;
        if (v != fa)
        {
            xOr[v] = xOr[u] ^ edge[e].w;
            Dfs(v, u);
        }
    }
}

void Insert(int x)
{
    int u = 0;
    for (int i = MAX_BIT; i >= 0; --i)
    {
        int cur = ((1 << i) & x) > 0 ? 1 : 0;
        if (!ch[u][cur])
        {
            memset(ch[sz], 0, sizeof(ch[sz]));
            ch[u][cur] = sz++;
        }
        u = ch[u][cur];
    }
}

void Insert()
{
    for (int i = 0; i < n; ++i)
    {
        Insert(xOr[i]);
    }
}

int Query(int x)
{
    int ret = 0, u = 0;

    for (int i = MAX_BIT; i >= 0; --i)
    {
        int cur = ((1 << i) & x) > 0 ? 1 : 0;
        if (ch[u][!cur])
        {
            ret |= (1 << i);
            u = ch[u][!cur];
        }
        else
        {
            u = ch[u][cur];
        }
    }

    return ret;
}

void Query()
{
    int ret = 0;

    for (int i = 0; i < n; ++i)
    {
        ret = max(ret, Query(xOr[i]));
    }

    printf("%d\n", ret);
}

int main()
{
    while (scanf("%d", &n) == 1)
    {
        Init();
        Read();
        Dfs(0, -1);
        Insert();
        Query();
    }

    return 0;
}
时间: 2024-11-25 11:25:21

poj - 3764 - The xor-longest Path(Trie)的相关文章

poj 1122 FDNY to the Rescue! (dijkstra)

FDNY to the Rescue! Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2475   Accepted: 755 Description The Fire Department of New York (FDNY) has always been proud of their response time to fires in New York City, but they want to make the

poj 2488 A Knight&#39;s Journey (DFS)

A Knight's Journey Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 34660   Accepted: 11827 Description Background The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey ar

poj 3903 &amp; poj 2533 最长上升子序列(LIS)

最长上升子序列. 做这道题之前先做了2533,再看这道题,感觉两道题就一模一样,于是用2533的代码直接交, TLE了: 回头一看,数据范围.2533 N:0~1000:3903 N :1~100000. 原因终归于算法时间复杂度. 也借这道题学习了nlgn的最长上升子序列.(学习链接:http://blog.csdn.net/dangwenliang/article/details/5728363) 下面简单介绍n^2 和 nlgn 的两种算法. n^2: 主要思想:DP: 假设A1,A2..

【POJ】1228 Grandpa&#39;s Estate(凸包)

http://poj.org/problem?id=1228 随便看看就能发现,凸包上的每条边必须满足,有相邻的边和它斜率相同(即共线或凸包上每个点必须一定在三点共线上) 然后愉快敲完凸包+斜率判定,交上去wa了QAQ.原因是忘记特判一个地方....因为我们求的凸包是三点共线的凸包,在凸包算法中我们叉积判断只是>0而不是>=0,那么会有一种数据为所有点共线的情况,此时求出来的凸包上的点是>原来的点的(此时恰好符合答案NO,因为可以在这条线外随便点一个点就是一个凸包了...)然后特判一下.

POJ 2965 The Pilots Brothers&#39; refrigerator (DFS)

题目:http://poj.org/problem?id=2965 也是以前就做过的题目,这次居然遇到了问题搞了一天. 关于最小步骤很容易就出来,DFS就可以,但是每一步是什么怎么也出不来了 DFS本质就是利用栈暴力,当出现正确结果的时候其过程都在栈中,我一直努力想还原这个栈,未果 然后思路大乱,然后问了RE,才发现根本不用这么麻烦,只需要建个存储步骤数组,在改变元素的时候记录并不停更新就好啦. 然后就简单的解决了问题:= = #include <stdio.h> #include <s

HDU 1247 Hat&#39;s words(Trie)

HDU 1247 Hat's words(Trie) ACM 题目地址: HDU 1247 Hat's words 题意: 给些单词,问每个单词是否能用另外两个单词拼出. 分析: 直接保存到trie里面,然后暴力切割查询即可. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: 1247.cpp * Create Date: 2014-09-24 11:04:11 * Descripton: */ #include <cstdio

【POJ 2409】 Let it Bead(Polya)

[POJ 2409] Let it Bead(Polya) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5378   Accepted: 3596 Description "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, t

POJ 2586:Y2K Accounting Bug(贪心)

Y2K Accounting Bug Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10024 Accepted: 4990 Description Accounting for Computer Machinists (ACM) has sufferred from the Y2K bug and lost some vital data for preparing annual report for MS Inc. Al

POJ 2029 Get Many Persimmon Trees(DP)

题目链接 题意 : 给你每个柿子树的位置,给你已知长宽的矩形,让这个矩形包含最多的柿子树.输出数目 思路 :数据不是很大,暴力一下就行,也可以用二维树状数组来做. 1 //2029 2 #include <stdio.h> 3 #include <string.h> 4 #include <iostream> 5 6 using namespace std ; 7 8 int mapp[110][110] ; 9 10 int main() 11 { 12 int N