poj3764 The XOR Longest Path【dfs】【Trie樹】
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
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樹】