poj - 3764
Posted hit_yjl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj - 3764相关的知识,希望对你有一定的参考价值。
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 8273 | Accepted: 1720 |
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 u and 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)
思路: 每个点存一下到根节点路径的异或和,这些值两两异或的最大值就是答案。
POJ不开O2,vector慢的不行,一直以为字典树写搓了TLE到绝望,试了三种不同的字典树写法,结果换成链式前向星快得飞起...加上之前瞎加的奇技淫巧的优化297ms跑进了前5
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 const int MaxN = 100000; 45 int n, p[MaxN + 15]; 46 struct Edge { 47 int v, w; 48 Edge () {} 49 Edge (int v, int w) : v(v), w(w) {} 50 } e[2 * MaxN + 15]; 51 52 int cnt, head[MaxN + 15], nex[MaxN + 15]; 53 void add_edge(int u, int v, int w) { 54 e[++cnt] = Edge(v, w); nex[cnt] = head[u]; head[u] = cnt; 55 e[++cnt] = Edge(u, w); nex[cnt] = head[v]; head[v] = cnt; 56 } 57 void dfs(int x, int pa) { 58 for (int i = head[x]; i; i = nex[i]) { 59 int y = e[i].v; 60 if (y == pa) continue; 61 p[y] = p[x] ^ e[i].w; 62 dfs(y, x); 63 } 64 } 65 int trie[2000015][2], tot; 66 void add(int x) { 67 int p = 1; 68 for (int i = 30; ~i; --i) { 69 int f = x >> i & 1; 70 if (!trie[p][f]) { 71 trie[p][f] = ++tot; 72 trie[tot][0] = trie[tot][1] = 0; 73 } 74 p = trie[p][f]; 75 } 76 } 77 int query(int x) { 78 int p = 1, y = 0; 79 for (int i = 30; ~i; --i) { 80 int f = x >> i & 1; 81 if (trie[p][!f]) { 82 y = y << 1 | !f; 83 p = trie[p][!f]; 84 } else { 85 y = y << 1 | f; 86 p = trie[p][f]; 87 } 88 } 89 return x ^ y; 90 } 91 int getint() { 92 int res = 0; char c = getchar(); 93 while (!isdigit(c)) c = getchar(); 94 while (isdigit(c)) { 95 res = res * 10 + c - ‘0‘; 96 c = getchar(); 97 } 98 return res; 99 } 100 int main() { 101 while (~scanf("%d", &n)) { 102 clr(head, 0), cnt = 0; 103 for (int i = 1; i < n; ++i) { 104 int u, v, w; 105 u = getint(); 106 v = getint(); 107 w = getint(); 108 //scanf("%d%d%d", &u, &v, &w); 109 add_edge(u, v, w); 110 } 111 dfs(0, -1); 112 tot = 1; trie[tot][0] = trie[tot][1] = 0; 113 int ans = 0; 114 for (int i = 0; i < n; ++i) { 115 add(p[i]); 116 int res = query(p[i]); 117 ans = max(ans, res); 118 } 119 printf("%d\n", ans); 120 } 121 return 0; 122 }
以上是关于poj - 3764的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3764 The xor-longest Path (字典树)
POJ 3764 - The xor-longest Path - [DFS+字典树变形]