您的位置:首页 > 其它

POJ 3764 The xor-longest Path(字典树 + 贪心)

2015-08-17 22:03 531 查看
题目链接:http://poj.org/problem?id=3764

题意:给出一棵N个点的树,定义两点间的异或权值为这两点间的所有边权的异或值,求树中最大的两点异或权值

思路:对于异或有性质 A ^ C = (A ^ B) ^ (B ^ C),故而树上两点A, C的异或值可以通过与两点分别于根节点的异或值再异或得到,这样可以先预处理出所有点到根节点的异或值,然后考虑这N个值如何选出两个值异或值最大,可以将每个值从高位到低位拆成二进制的串插入字典树,每当插入完成后就在字典树上进行遍历,因为是从高位到低位,所以每次应保证高位的值尽量能取到,所以每次尽量找与当前位相反的结点进行遍历

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <climits>
#include <functional>
#include <deque>
#include <ctime>
#include <string>

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#pragma comment(linker, "/STACK:102400000,102400000")

using namespace std;

const int maxn = 100010;
const int maxm = 6000010;

int cnt, head[maxn], dis[maxn];

struct Edge
{
int to, w, next;
} edge[maxn << 1];

void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
}

void addedge(int u, int v, int w)
{
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt++;
}

void dfs(int u, int fa, int w)
{
dis[u] = w;
for (int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
if (v == fa) continue;

dfs(v, u, w ^ edge[i].w);
}
}

struct Trie
{
int ch[maxm][2];
int sz;

void init()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}

void insert(int num)
{
int u = 0;
for (int i = 30; i >= 0; i--)
{
int w;
if (num & (1 << i))
w = 1;
else
w = 0;

if (!ch[u][w])
{
memset(ch[sz], 0, sizeof(ch[sz]));
ch[u][w] = sz++;
}
u = ch[u][w];
}
}

int query(int num)
{
int u = 0, res = 0;
for (int i = 30; i >= 0; i--)
{
int w;
if (num & (1 << i))
w = 1;
else
w = 0;

if (ch[u][w ^ 1])
{
u = ch[u][w ^ 1];
res *= 2;
res += 1;
}
else
{
u = ch[u][w];
res *= 2;
}
}
return res;
}
} tr;

int main()
{
int n;
while (~scanf("%d", &n))
{
init();
for (int i = 0; i < n - 1; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
addedge(v, u, w);
}
dfs(0, -1, 0);

// for (int i = 0; i < n; i++)
// printf("%d ", dis[i]);

tr.init();
int ans = 0;
for (int i = 0; i < n; i++)
{
tr.insert(dis[i]);
ans = max(ans, tr.query(dis[i]));
}
cout << ans << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: