【01Trie树_数组中找到两个数异或值最大】POJ 3764 The xor-longest Path

 POJ 3764 The xor-longest Path

  • 题意:给出一个无根树,找到这棵树上的一条路径使得路径上的所有边权值异或最大。

思路

首先我们要知道一件事情!

定义dis[ i ][ j ]为结点 i 和结点 j 之间的路径边权异或值。那么dis[ i ][ j ] = dis[ k ][ i ] ^ dis[ k ][ j ]。 我们可以使得k = 0,由此我们可以得到结点0到树上其他结点的路径上的异或值dis[ i ]

所以我们将dis[ i ] 【其中 i = [ 1, n )】建立01字典树。我们遍历一遍dis[ i ]找到字典树上和其异或值最大的值。取最大ans = max(ans, dis[ i ] ^ Search(dis[ i ]))

这样就结束了嘛?

当然结果是WA!

因为漏掉了dis[ i ]!!!!也就是经过结点0的路径啊!!!www。ans = max(ans, dis[ i ])

AC!!!!


AC CODE

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 100000 + 7;
inline int read()
{
    int x = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    return x * f;
}
struct EDGE{
    int adj, to, val;
    EDGE(int a = -1, int b = 0, int c = 0): adj(a), to(b), val(c){}
}edge[maxN << 1];
int cnt, head[maxN];
int tire[maxN * 31 * 2][2], tot, va[maxN * 31 * 2];
void Clear(int rt)
{
    for(int i = 0; i < 2; i ++ )
        tire[rt][i] = 0;
}
void init()
{
    cnt = 0; tot = 0; Clear(0);
    memset(head, -1, sizeof(head));
}
void add_edge(int u, int v, int w)
{
    edge[cnt] = EDGE(head[u], v, w);
    head[u] = cnt ++ ;
}
int dis[maxN];
void dfs(int x, int fa, int val)
{
    for(int i = head[x]; ~i; i = edge[i].adj)
    {
        if(edge[i].to != fa)
        {
            dis[edge[i].to] = val ^ edge[i].val;
            dfs(edge[i].to, x, dis[edge[i].to]);
        }
    }
}
void Insert(int num)
{
    int rt = 0;
    for(int i = 30; i >= 0; i -- )
    {
        int id = num >> i & 1;
        if(!tire[rt][id]) { tire[rt][id] = ++ tot; Clear(tot); }
        rt = tire[rt][id];
    }
    va[rt] = num;
}
int Search(int num)
{
    int rt = 0;
    for(int i = 30; i >= 0; i -- )
    {
        int id = num >> i & 1;
        if(tire[rt][id ^ 1]) rt = tire[rt][id ^ 1];
        else rt = tire[rt][id];
    }
    return va[rt];
}
int n;
int main()
{
    while(~scanf("%d", &n))
    {
        init();
        for(int i = 0; i < n - 1; i ++ )
        {
            int u, v, w;
            u = read(); v = read(); w = read();
            add_edge(u, v, w);
            add_edge(v, u, w);
        }
        dfs(0, -1, 0);
        int ans = 0;
        for(int i = 1; i < n; i ++ )
        {
            Insert(dis[i]);
            ans = max(ans, dis[i]);
        }
        for(int i = 1; i < n; i ++ )
            ans = max(ans, dis[i] ^ Search(dis[i]));
        printf("%d\n", ans);
    }
    return 0;
}
发布了242 篇原创文章 · 获赞 68 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/104173670