当前位置 : 主页 > 编程语言 > c语言 >

POJ - 3764 XOR&&dfs 01字典树

来源:互联网 收集:自由互联 发布时间:2023-09-06
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§=\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. Gi

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§=\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;
	}
}
网友评论