对于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.
View Code

 

posted on 2014-09-23 21:04  acphile  阅读(215)  评论(0编辑  收藏  举报