您的位置:首页 > 其它

POJ 3764 The xor-longest Path

2012-08-02 16:26 232 查看
建立字典树,树的结点记录根结点到该结点的连续异或值。

由(a ^ c) ^ (b ^ c) == a ^ b 可得任意两结点的异或值,等于两结点之间这条路的连续异

或值。由此把每个结点的值插入01字典树,从二进制31位~0位,并查找,尽可能的向

每一位的不同方向查找(这样异或这一位能得1),取最大值。位运算还得继续学习。

/*Accepted    44068K    875MS    C++    1756B    2012-08-02 16:10:05*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

const int MAXN = 210000;
typedef struct
{
int to[2];
int num;
}Trie;

Trie t[MAXN << 4];
int first[MAXN], next[MAXN], u[MAXN], v[MAXN], w[MAXN];
int tp, n, ans;

void insert(int x, int site, int bit)
{
if(bit != -1)
{
if(t[site].to[x >> bit & 1] == -1)
t[site].to[x >> bit & 1] = ++ tp;
insert(x, t[site].to[x >> bit & 1], bit - 1);
}
else
{
t[site].num = x;
}
}

void cal(int x, int site, int bit)
{
if(-1 == bit)
{
int y = x ^ t[site].num;
if(y > ans)
ans = y;
}
else if(t[site].to[~ x >> bit & 1] != -1)
{
cal(x, t[site].to[~ x >> bit & 1], bit - 1);
}
else
{
cal(x, t[site].to[x >> bit & 1], bit - 1);
}
}

void calc(int x)
{
cal(x, 0, 31);
insert(x, 0, 31);
}

void addedge(int u1, int v1, int w1, int e)
{
next[e] = first[u1];
first[u1] = e;
u[e] = u1, v[e] = v1, w[e] = w1;
}

void ReadTree()
{
int u1, v1, w1, e;
memset(first, -1, sizeof (int) * (n + 1));
for(e = 1; e < n; e ++)
{
scanf("%d%d%d", &u1, &v1, &w1);
addedge(u1, v1, w1, e);
addedge(v1, u1, w1, e + n);
}
}

void build(int e, int p, int last)
{
calc(last);
while(e != -1)
{
if(v[e] != p)
build(first[v[e]], u[e], w[e] ^ last);
e = next[e];
}
}

int main()
{
while(scanf("%d", &n) == 1)
{
tp = ans = 0;
memset(t, -1, sizeof (Trie)*((n + 1) << 5));
ReadTree();
build(first[u[1]], -1, 0);
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: