描述
In an edge-weighted tree, the xor-length of a path pis 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?
输入
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 u and v of length w.
输出
For each test case output the xor-length of the xor-longest path.
样例输入
4
0 1 3
1 2 4
1 3 6
样例输出
7
提示
The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)
1 #include < algorithm > 2 #include < cstdio > 3 #include < cstring > 4 #include < vector > 5 using namespace std; 6 7 const int MAXN = 100010; 8 const int MAXM = 200010; 9 struct Trie { 10 Trie *children[2]; 11 int value; 12 } root, pool[MAXN << 5], *ptr, emptyNode; 13 // Trie树是一棵二叉树,左孩子表示当前二进制位为0,右孩子表示当前二进制位为1 14 // 叶子节点额外保存value,表示当前路径对应的数,如根-左-右-右这个节点的value为(011)2=3 15 16 int n; 17 // 节点个数 18 19 int head[MAXN], succeed[MAXM], vertex[MAXM], weight[MAXM], now; 20 // head,succeed使用链表保存边表;vertex,weight存每条边的终点以及权值 21 22 int rootXor[MAXN]; 23 // 每个点到根的路径的xor值 24 25 void addEdge(int u, int v, int w) { 26 // 往链表中添加一条u->v,权值为w的边 27 ________(1)________ 28 // 新的节点的后继为u节点原来的链表头 29 vertex[now] = v; 30 // 新的边的终点为v 31 weight[now] = w; 32 // 新的边的权值为w 33 head[u] = now++; 34 // 指定u节点新的链表头为now 35 } 36 37 void readTree() { 38 // 读入树 39 memset(head, -1, sizeof head); 40 now = 0; 41 for (int i = 0; i < n - 1; i++) { 42 int u, v, w; 43 scanf("%d%d%d", &u, &v, &w); 44 addEdge(u, v, w); 45 addEdge(v, u, w); 46 } 47 } 48 49 void DFS(int x = 0, int father = -1) { 50 // DFS求出每个点到0号点的路径的xor值,并填到rootXor数组中 51 // 参数x表示当前递归到的节点,father表示当前点的父亲 52 for (int now = head[x]; now != -1; now = succeed[now]) { 53 // 遍历x节点的链表,找到所有x的出边 54 int y = vertex[now]; 55 int w = weight[now]; 56 // 从x到y有一条权值为w的边 57 if (________(2)________) 58 continue; 59 // 忽略返回父亲的边 60 rootXor[y] = ________(3)________; 61 // 计算rootXor[y]的值,为y到0号点的路径的xor值 62 DFS(y, x); 63 } 64 } 65 66 int getNthBit(int value, int nBit) { 67 return value >> nBit & 1; 68 } 69 70 void insertTrie(Trie *node, int value, int nBit) { 71 // 往Trie中插入value 72 // 当前在node这个节点,处理到value的第nBit个bit 73 // 如果nBit为-1,说明已经处理完毕,node为叶子节点 74 if (nBit == -1) 75 node->value = ________(4)________; 76 else { 77 bool bit = ________(5)________; 78 // bit为0说明当前的节点应为node的左孩子 79 // bit为1说明当前的节点应为node的右孩子 80 if (!node->children[bit]) { 81 node->children[bit] = ptr++; 82 *node->children[bit] = emptyNode; 83 } 84 insertTrie(node->children[bit], value, nBit - 1); 85 } 86 } 87 88 void buildTrie() { 89 // 将所有rootXor[i]插入Trie中 90 root = emptyNode; 91 ptr = pool; 92 for (int i = 0; i < n; i++) 93 insertTrie(&root, rootXor[i], 30); 94 } 95 96 int queryTrie(Trie *node, int value, int nBit) { 97 // 在Trie中查询与value的xor值最大的答案 98 // 当前在node这个节点,处理到value的第nBit个bit 99 // 如果nBit为-1,说明已经处理完毕,node为叶子节点 100 if (nBit == -1) 101 return node->value ^ value; 102 else { 103 bool bit = ________(5)________; 104 // 同上 105 if (node->children[!bit]) 106 return queryTrie(node->children[!bit], value, nBit - 1); 107 else 108 return queryTrie(node->children[bit], value, nBit - 1); 109 } 110 } 111 112 int getAns() { 113 // 将所有rootXor[i]在Trie中查询最大的xor答案 114 int ans = 0; 115 for (int i = 0; i < n; i++) 116 ans = max(ans, queryTrie(&root, rootXor[i], 30)); 117 return ans; 118 } 119 120 int main() { 121 while (scanf("%d", &n) == 1) { 122 readTree(); 123 DFS(); 124 buildTrie(); 125 printf("%d\n", getAns()); 126 } 127 return 0; 128 }
填空答案:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <string.h> 3 #include <algorithm> 4 #include <stack> 5 #include <string> 6 #include <math.h> 7 #include <queue> 8 #include <stdio.h> 9 #include <string.h> 10 #include <set> 11 #include <vector> 12 #include <fstream> 13 #define maxn 400005 14 #define inf 999999 15 #define cha 127 16 using namespace std; 17 18 const int MAXN = 100010; 19 const int MAXM = 200010; 20 struct Trie { 21 Trie *children[2]; 22 int value; 23 } root, pool[MAXN << 5], *ptr, emptyNode; 24 // Trie树是一棵二叉树,左孩子表示当前二进制位为0,右孩子表示当前二进制位为1 25 // 叶子节点额外保存value,表示当前路径对应的数,如根-左-右-右这个节点的value为(011)2=3 26 27 int n; 28 // 节点个数 29 30 int head[MAXN], succeed[MAXM], vertex[MAXM], weight[MAXM], now; 31 // head,succeed使用链表保存边表;vertex,weight存每条边的终点以及权值 32 33 int rootXor[MAXN]; 34 // 每个点到根的路径的xor值 35 36 void addEdge(int u, int v, int w) { 37 // 往链表中添加一条u->v,权值为w的边 38 succeed[now] = head[u]; 39 // 新的节点的后继为u节点原来的链表头 40 vertex[now] = v; 41 // 新的边的终点为v 42 weight[now] = w; 43 // 新的边的权值为w 44 head[u] = now++; 45 // 指定u节点新的链表头为now 46 } 47 48 void readTree() { 49 // 读入树 50 memset(head, -1, sizeof head); 51 now = 0; 52 for (int i = 0; i < n - 1; i++) { 53 int u, v, w; 54 scanf("%d%d%d", &u, &v, &w); 55 addEdge(u, v, w); 56 addEdge(v, u, w); 57 } 58 } 59 60 void DFS(int x = 0, int father = -1) { 61 // DFS求出每个点到0号点的路径的xor值,并填到rootXor数组中 62 // 参数x表示当前递归到的节点,father表示当前点的父亲 63 for (int now = head[x]; now != -1; now = succeed[now]) { 64 // 遍历x节点的链表,找到所有x的出边 65 int y = vertex[now]; 66 int w = weight[now]; 67 // 从x到y有一条权值为w的边 68 if (y==father) 69 continue; 70 // 忽略返回父亲的边 71 rootXor[y] = rootXor[x]^w; 72 // 计算rootXor[y]的值,为y到0号点的路径的xor值 73 DFS(y, x); 74 } 75 } 76 77 int getNthBit(int value, int nBit) { 78 return value >> nBit & 1; 79 } 80 81 void insertTrie(Trie *node, int value, int nBit) { 82 // 往Trie中插入value 83 // 当前在node这个节点,处理到value的第nBit个bit 84 // 如果nBit为-1,说明已经处理完毕,node为叶子节点 85 if (nBit == -1) 86 node->value = value; 87 else { 88 bool bit = getNthBit(value, nBit); 89 // bit为0说明当前的节点应为node的左孩子 90 // bit为1说明当前的节点应为node的右孩子 91 if (!node->children[bit]) { 92 node->children[bit] = ptr++; 93 *node->children[bit] = emptyNode; 94 } 95 insertTrie(node->children[bit], value, nBit - 1); 96 } 97 } 98 99 void buildTrie() { 100 // 将所有rootXor[i]插入Trie中 101 root = emptyNode; 102 ptr = pool; 103 for (int i = 0; i < n; i++) 104 insertTrie(&root, rootXor[i], 30); 105 } 106 107 int queryTrie(Trie *node, int value, int nBit) { 108 // 在Trie中查询与value的xor值最大的答案 109 // 当前在node这个节点,处理到value的第nBit个bit 110 // 如果nBit为-1,说明已经处理完毕,node为叶子节点 111 if (nBit == -1) 112 return node->value ^ value; 113 else { 114 bool bit = getNthBit(value,nBit); 115 // 同上 116 if (node->children[!bit]) 117 return queryTrie(node->children[!bit], value, nBit - 1); 118 else 119 return queryTrie(node->children[bit], value, nBit - 1); 120 } 121 } 122 123 int getAns() { 124 // 将所有rootXor[i]在Trie中查询最大的xor答案 125 int ans = 0; 126 for (int i = 0; i < n; i++) 127 ans = max(ans, queryTrie(&root, rootXor[i], 30)); 128 return ans; 129 } 130 131 int main() { 132 while (scanf("%d", &n) == 1) { 133 readTree(); 134 DFS(); 135 buildTrie(); 136 printf("%d\n", getAns()); 137 } 138 return 0; 139 }