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;
}