现在的位置: 首页 > 算法 > 正文

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

2019年08月28日 算法 ⁄ 共 1420字 ⁄ 字号 评论关闭

题意:一棵 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;
}

抱歉!评论已关闭.