1. 程式人生 > >poj3764 The XOR Longest Path【dfs】【Trie樹】

poj3764 The XOR Longest Path【dfs】【Trie樹】

print 思路 https per span dfs pre between col

The xor-longest Path
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 10038 Accepted: 2040

Description

In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:

技術分享圖片

⊕ is the xor operator.

We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?  

Input

The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node uand v of length w.

Output

For each test case output the xor-length of the xor-longest path.

Sample Input

4
0 1 3
1 2 4
1 3 6

Sample Output

7

Hint

The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)

Source

題意:

給一棵帶邊權的樹,想找得到兩個點,他們的路徑上的權值異或最小。

思路:

首先我們任意找一個作為根,可以用dfs求出其他節點到根的路徑的異或,記為xordis

那麽對於樹上的任意兩個節點i, j,i到j的路徑的異或和應該是xordis[i] ^ xordis[j]

因為i到j的路徑,相當於i到根,根到j,其中重疊的部分,他們的異或值正好是0

因此這道題就變成了找兩點異或值最小,https://www.cnblogs.com/wyboooo/p/9824293.html 和這道題就差不多了

最後還需要註意,search找到的最大值是除根以外的,還需要和xordis比較一下,取較大值。

  1 #include <iostream>
  2 #include <set>
  3 #include <cmath>
  4 #include <stdio.h>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <map>
  8 using namespace std;
  9 typedef long long LL;
 10 #define inf 0x7f7f7f7f
 11 
 12 int n;
 13 const int maxn = 1e5 + 5;
 14 struct edge{
 15     int v, w;
 16     int nxt;
 17 }e[maxn * 2];
 18 int head[maxn], tot = 0;
 19 int xordis[maxn];
 20 int trie[maxn * 32 + 5][3], treetot = 1;
 21 
 22 void addedge(int u, int v, int w)
 23 {
 24     e[tot].v = v;
 25     e[tot].w = w;
 26     e[tot].nxt = head[u];
 27     head[u] = tot++;
 28     e[tot].v = u;
 29     e[tot].w = w;
 30     e[tot].nxt = head[v];
 31     head[v] = tot++;
 32 }
 33 
 34 void dfs(int rt, int fa)
 35 {
 36     for(int i = head[rt]; i != -1; i = e[i].nxt){
 37         int v = e[i].v;
 38         if(v == fa)continue;
 39         xordis[v] = xordis[rt] ^ e[i].w;
 40         dfs(v, rt);
 41     }
 42 }
 43 
 44 void init()
 45 {
 46     memset(head, -1, sizeof(head));
 47     tot = 0;
 48     memset(xordis, 0, sizeof(xordis));
 49     memset(trie, 0, sizeof(trie));
 50 }
 51 
 52 void insertt(int x)
 53 {
 54     int p = 1;
 55     for(int i = 30; i >= 0; i--){
 56         int ch = x >> i & 1;
 57         if(trie[p][ch] == 0){
 58             trie[p][ch] = ++tot;
 59         }
 60         p = trie[p][ch];
 61     }
 62 }
 63 
 64 int searchh(int x)
 65 {
 66     int p = 1, ans = 0;
 67     for(int i = 30; i >= 0; i--){
 68         int ch = x >> i & 1;
 69         if(trie[p][ch ^ 1]){
 70             p = trie[p][ch ^ 1];
 71             ans |= 1 << i;
 72         }
 73         else{
 74             p = trie[p][ch];
 75         }
 76     }
 77     return ans;
 78 }
 79 
 80 int main()
 81 {
 82     while(scanf("%d", &n) != EOF){
 83         init();
 84         for(int i = 0; i < n - 1; i++){
 85             int u, v, w;
 86             scanf("%d%d%d", &u, &v, &w);
 87             addedge(u, v, w);
 88         }
 89         dfs(0, -1);
 90 
 91         /*for(int i = 0; i < n; i++){
 92             printf("%d\n", xordis[i]);
 93         }*/
 94 
 95         int ans = 0;
 96         for(int i = 1; i < n; i++){
 97             insertt(xordis[i]);
 98             //cout<<searchh(xordis[i])<<endl;
 99             ans = max(ans, searchh(xordis[i]));
100             ans = max(ans, xordis[i]);
101         }
102         printf("%d\n", ans);
103     }
104     return 0;
105 }

poj3764 The XOR Longest Path【dfs】【Trie樹】