标签:register ref mem 二进制 sdi website gis space 输入格式
给定一棵 N 个节点的树,树上的每条边都有一个权值。从数中选择两个点 x 和 y ,把从 x 到 y 路径上的所有边权 xor 起来,得到的结果最大是多少?
显然, \(d[u]=d[fa_u] \ xor \ w_{u,fa_u}\) ,于是我们可以通过一遍 bfs 来求出每个节点到根节点的 d[i] 。
然后问题转化为求出最大的 \(d[u] \ xor \ d[v]\) 。
根据 xor 运算的性质:相同为 0 ,不同为 1 。我们可以用一棵 trie 树将 d[i] 的二进制位储存下来,并贪心的在 trie 树中寻找与当前位的数值相反的数,如果有,则跳到相反数中;如果没有,则跳到相同的数中,然后求出寻找过程中得到二进制数与当前数的 xor 值,最后取 max 就好了。
一些废话:这道题改了我半天,然后又对着标程改,发现没毛病......只是这个标程有点烦,是用的多组测试数据的输入格式,在 WA 了 INF 遍后,重新看题,发现题目就是多组测试数据......怎么就不给一个多组测试数据的样例呢......
//=========================
// author:tyqs
// date:2019.12.7
// website:http://tyqs.kim
//=========================
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100003
#define il inline
#define re register
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
typedef long long ll;
template <typename T> inline void read(T &x) {
T f = 1; x = 0; char c;
for (c = getchar(); !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
x *= f;
}
struct edge {
int to, nxt, val;
} e[N<<1];
int n, ans;
int head[N<<1], cnt, d[N];
int trie[N*32][2], tot;
void dfs(int u, int fa) {
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to, w = e[i].val;
if (v == fa) continue;
d[v] = d[u] ^ w;
dfs(v, u);
}
}
void insert(int u, int v, int w) {
e[++cnt] = (edge){v, head[u], w};
head[u] = cnt;
}
void insert_trie(int x) {
int p = 1;
for (int i = 30; i >= 0; --i) {
int c = x >> i & 1;
if (!trie[p][c]) trie[p][c] = ++tot;
p = trie[p][c];
}
}
int search(int x) {
int p = 1, ret = 0;
for (int i = 30; i >= 0; --i) {
int c = x >> i & 1;
if (!trie[p][c^1]) p = trie[p][c];
else ret |= (1 << i), p = trie[p][c^1];
}
return ret;
}
int main() {
int u, v, w;
while (~scanf("%d", &n)) {
memset(head, 0, sizeof head);
memset(d, 0, sizeof d);
memset(trie, 0, sizeof trie);
cnt = ans = 0; tot = 1;
for (int i = 1; i < n; ++i) {
read(u), read(v), read(w);
insert(u, v, w), insert(v, u, w);
}
dfs(u, -1);
tot = 1;
for (int i = 0; i < n; ++i) {
insert_trie(d[i]);
ans = max(ans, search(d[i]));
}
printf("%d\n", ans);
}
return 0;
}
「POJ 3764」The xor-longest Path
标签:register ref mem 二进制 sdi website gis space 输入格式
原文地址:https://www.cnblogs.com/hlw1/p/12260610.html