POJ - 3764 XOR&&dfs 01字典树

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:

{xor}length(p)=\oplus{e \in p}w(e)
⊕ 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
For each test case output the xor-length of the xor-longest path.
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)

先dfs 出根节点到各个节点的 xor 和,然后就是在这样的一个序列中选出两个xor最大;
那么字典树即可;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 6000005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const long long int mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-6
#define pll pair<ll,ll>



ll quickpow(ll a, ll b) {
    ll ans = 1;
    a = a % mod;
    while (b > 0) {
        if (b % 2)ans = ans * a;
        b = b / 2;
        a = a * a;
    }
    return ans;
}

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a%b);
}

int d[maxn][2], cnt;
struct edge {
    int to, w, nxt;
    edge(){}
    edge(int x,int y,int z):to(x),w(y),nxt(z){}

}e[500005];

int num[200005], vis[200005], tot, head[200005];
void addedge(int from, int to, int w) {
    e[tot] = edge(to, w, head[from]);
    head[from] = tot++;
}

void dfs(int v, int w) {
    vis[v] = 1;
    num[v] = w;
    for (int i = head[v]; i != -1; i = e[i].nxt) {
        if (!vis[e[i].to]) {
            dfs(e[i].to, w^e[i].w);
        }
    }
}

void add(int x) {
    int p = 1;
    for (int i = 30; i >= 0; i--) {
        if (d[p][(x >> i) & 1] == 0)
            d[p][(x >> i) & 1] = ++cnt;
        p = d[p][(x >> i) & 1];
    }
}

int fid(int x) {
    int p = 1, ans = 0;
    for (int i = 30; i >= 0; i--) {
        int t = (x >> i) & 1;
        if (d[p][t ^ 1]) {
            ans += (1 << i);
            p = d[p][t ^ 1];
        }
        else p = d[p][t];
    }
    return ans;
}
int main()
{
    //ios::sync_with_stdio(false);
    int n;
    while (scanf("%d",&n)!=EOF) {
        tot = 0;
        ms(d); ms(vis);
        memset(head, -1, sizeof(head));
        cnt = 1;
        for (int i = 1; i < n; i++) {
            int x, y, w;
            //cin >> x >> y >> w;
            scanf("%d%d%d", &x, &y, &w);
            addedge(x, y, w); addedge(y, x, w);
        }
        dfs(0, 0);
        int ans = 0;
        for (int i = 0; i < n; i++) {
            add(num[i]);
            ans = max(ans, fid(num[i]));
        }
        cout << ans << endl;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40273481/article/details/81393793