只有01的字典树。
大概就是(偷图.jpg)
洛谷:P4551 最长异或路径
维护每个点到根的异或和。
然后我们对于每个点的异或和去找最优的字典树走法。
从最高位开始往另一位走。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> pii; typedef tuple<int,int,int> tu; const int N = 1e5 + 5; const int M = 1e4 + 5; const double eps = 1e-10; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define dbg(ax) cout << "now this num is " << ax << endl; inline int read() { int f = 1;int x = 0;char c = getchar(); while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } inline long long ADD(long long x,long long y) {return (x + y) % Mod;} inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;} inline long long MUL(long long x,long long y) {return x * y % Mod;} int n; struct Node{int to,dis;}; vector<Node> G[N]; int tree[N * 31][2],tot = 0,a[N]; void insert(int val) { int x = 0; for(int i = 30;i >= 0;--i) { int g = ((val >> i) & 1); if(tree[x][g] == 0) tree[x][g] = ++tot; x = tree[x][g]; } } int query(int val) { int mx = 0,x = 0; for(int i = 30;i >= 0;--i) { int g = (val >> i) & 1; if(tree[x][g ^ 1] != 0) { mx += (1 << i); x = tree[x][g ^ 1]; } else x = tree[x][g]; } return mx; } int ans = 0; void dfs(int u,int fa,int val) { if(u != 1) { insert(val); ans = max(ans,val); a[u] = val; } for(auto v : G[u]) { if(v.to == fa) continue; dfs(v.to,u,val ^ v.dis); } } void solve() { n = read(); for(int i = 1;i < n;++i) { int u,v,w;u = read(),v = read(),w = read(); G[u].push_back(Node{v,w}); G[v].push_back(Node{u,w}); } dfs(1,0,0); for(int i = 2;i <= n;++i) ans = max(ans,query(a[i])); printf("%d\n",ans); } int main() { solve(); system("pause"); return 0; }View Code