AcWing:. 144 exclusive-OR of the longest path (dfs + 01 trie)

Given a tree, the tree has the edge weights.

XOR tree path length is defined as the XOR and the weights of all edges on the path:

formula.png

⊕ is XOR symbol.

To a tree with n nodes given above, you can find a different path or maximum length of it?

Input Format

The first row contains an integer n, the number of nodes of the tree.

Next, n-1 rows, each row comprising three integers u, v, W, expressed between node u and node v an edge weight is w.

Output Format

Output an integer, represents the maximum path length XOR XOR and maximum.

data range

1n1000001≤n≤100000,
0u,v<n0≤u,v<n,
0w<2310≤w<231

Sample input:

4
0 1 3
1 2 4
1 3 6

Sample output:

7

Sample interpretation

Sample XORed longest path should 0-> 1-> 2, value of 7 (= 3 ⊕ 4)

 

Algorithm: dfs + 01 trie

Solution: set D [x] represents the edge weight xor values ​​of all the root node to the path x, clearly:  

                             D[x] = D[father(x) ] xor weight(x,father(x)) 

According to the above equation, we can use dfs, traversing from the root, followed by recording each path.

And the same or different and the two numbers is 0, then, as long as the requirements of D [x] array as do the most exclusive line or on the same (or different maximum: https://www.cnblogs.com/buhuiflydepig /p/11306057.html ).

You need to know that it is a tree.

For example: 0 -> 1 -> 2 - Results> 5 is 4, then kept D [5] in.

   0 - Results> 1 is 1, the presence of D [1] in.

Now we need to claim 1 - Result> 5, it is as long as the D [1] ^ D [5] on the line, where the same XOR to zero, in accordance with the nature of this, the results can be drawn.

 

#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

const int maxn = 1e5+7;

vector<pair<int, int> > g[maxn];
int tree[maxn * 32][2];
int d[maxn];
int tot;

void dfs(int u, int fa) {
    int len = g[u].size();
    for(int i = 0; i < len; i++) {
        pair<int, int> v = g[u][i];
        if(v.first != fa) {     
            d[v.first] = d[u] ^ v.second;
            dfs(v.first, u);
        }
    }
}

void insert(int x) {
    int root = 0;
    for(int i = 30; i >= 0; i--) {
        int idx = (x >> i) & 1;
        if(tree[root][idx] == 0) {
            tree[root][idx] = ++tot;
        }
        root = tree[root][idx];
    }
}

int search(int x) {
    int root = 0;
    int res = 0;
    for(int i = 30; i >= 0; i--) {
        int idx = (x >> i) & 1;
        if(tree[root][1 ^ idx] != 0) {
            root = tree[root][1 ^ idx];
            res |= (1 << i);
        } else {
            root = tree[root][idx];
        }
    }
    return res;
}

int main() {
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n - 1; i++) {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        g[u].push_back(make_pair(v, w));
        g[v].push_back(make_pair(u, w));
    }
    dfs(0, -1);
    int ans = 0;
    for(int i = 0; i < n; i++) {
        insert(d[i]);
        ans = max(ans, search(d[i]));
    }
    cout << ans << endl;
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/buhuiflydepig/p/11307937.html