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

来源:互联网 发布:修改java环境变量 编辑:程序博客网 时间:2024/04/30 04:28

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


0 0
原创粉丝点击