对于xor有一个非常重要的性质
A xor B xor B=A 并且满足交换律和结合律
这道题是求无根树上最长的xor路径
我们知道,无根树的题目我们都是要想办法转化为有根树来处理
当我们确定了一个根,根到每个节点i的xor路径f[i]可知
则在树中,任意两个节点ij间的xor路径长度即为f[i] xor f[j]
为什么,利用之前的性质我们可以知道
路径长度=d[i,LCA] xor d[LCA,j]=d[i,LCA] xor d[LCA,root] xor d[root,LCA] xor d[LCA,j]=f[i] xor f[j]
这样就转化为一个经典的问题,在一堆数中找两个数是xor值最大
这个我们可以将所有值得二进制建成一棵trie,
然后穷举每个数,遍历trie树找到和这个数xor值最大的数(贪心)
PS:这道题和poj3764一样,只不过bzoj1954标号是1~n,poj是0~n-1
但我改了标号始终在poj上WA……求指教
code(按bzoj1954)
1 type node=record 2 point,next,cost:longint; 3 end; 4 5 var son:array[0..3200010,0..1] of longint; 6 p,f:array[0..200010] of longint; 7 v:array[0..210010] of boolean; 8 edge:array[0..400010] of node; 9 ans,m,n,len,t,r,i,x,y,z:longint; 10 11 function max(a,b:longint):longint; 12 begin 13 if a>b then exit(a) else exit(b); 14 end; 15 16 procedure add(x,y,z:longint); 17 begin 18 inc(len); 19 edge[len].point:=y; 20 edge[len].cost:=z; 21 edge[len].next:=p[x]; 22 p[x]:=len; 23 end; 24 25 procedure build(x:longint); 26 var p,i,y:longint; 27 begin 28 p:=1; 29 for i:=30 downto 0 do 30 begin 31 y:=(1 shl i) and x; 32 if y<>0 then y:=1; 33 if son[p,y]=-1 then 34 begin 35 inc(t); 36 son[p,y]:=t; 37 end; 38 p:=son[p,y]; 39 end; 40 end; 41 42 procedure dfs(x:longint); 43 var i,y:longint; 44 begin 45 i:=p[x]; 46 v[x]:=true; 47 while i<>-1 do 48 begin 49 y:=edge[i].point; 50 if not v[y] then 51 begin 52 f[y]:=f[x] xor edge[i].cost; 53 dfs(y); 54 end; 55 i:=edge[i].next; 56 end; 57 end; 58 59 function getans(x:longint):longint; 60 var y,p,s,i:longint; 61 begin 62 p:=1; 63 s:=0; 64 for i:=30 downto 0 do 65 begin 66 y:=(1 shl i) and x; 67 if y<>0 then y:=1; 68 if son[p,1-y]<>-1 then 69 begin 70 s:=s+1 shl i; 71 p:=son[p,1-y]; 72 end 73 else p:=son[p,y]; 74 end; 75 exit(s); 76 end; 77 78 begin 79 while not eof do 80 begin 81 readln(n); 82 fillchar(p,sizeof(p),255); 83 len:=0; 84 for i:=1 to n-1 do 85 begin 86 readln(x,y,z); 87 // inc(x); 88 // inc(y); 89 add(x,y,z); 90 add(y,x,z); 91 end; 92 fillchar(v,sizeof(v),false); 93 fillchar(son,sizeof(son),255); 94 f[1]:=0; 95 t:=1; 96 dfs(1); 97 for i:=1 to n do 98 build(f[i]); 99 100 ans:=0; 101 for i:=2 to n do 102 ans:=max(ans,getans(f[i])); 103 writeln(ans); 104 end; 105 end.