码迷,mamicode.com
首页 > 其他好文 > 详细

ACM学习历程—POJ 3764 The xor-longest Path(xor && 字典树 && 贪心)

时间:2015-11-11 20:49:14      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://poj.org/problem?id=3764

 

题目大意是在树上求一条路径,使得xor和最大。

由于是在树上,所以两个结点之间应有唯一路径。

xor(u, v) = xor(0, u)^xor(0, v)

所以如果预处理出0结点到所有结点的xor路径和,问题就转换成了求n个数中取出两个数,使得xor最大。

这个之前用字典树处理过类似问题。

 

代码:

技术分享
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long

using namespace std;

const int maxN = 100005;

//求n个数中取出两个数能xor的最大值
//Trie Tree字典树
//len*n, len为数的二进制最大长度
const int len = 31;//len表示数的二进制最大长度
struct Trie
{
    int next[2];
}tree[maxN*len];
int cntTree;

void initTree()
{
    cntTree = 0;
    memset(tree, -1, sizeof(tree));
}

void add(int x)
{
    int now = 0;
    bool k;
    for (int i = len; i >= 0; i--)
    {
        k = x&(1<<i);
        if (tree[now].next[k] == -1)
            tree[now].next[k] = ++cntTree;
        now = tree[now].next[k];
    }
}

//返回当前数中能和x合成最大数的数
int query(int x)
{
    int v = 0, now = 0;
    bool k;
    for (int i = len; i >= 0; i--)
    {
        k = x&(1<<i);
        if (tree[now].next[!k] != -1)
            k = !k;
        v = v|(k<<i);
        now = tree[now].next[k];
    }
    return v;
}

//链式前向星
struct Edge
{
    int to, next;
    int val;
}edge[maxN*2];

int head[maxN], cnt;

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

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

int n, p[maxN];

void dfs(int now)
{
    int to;
    for (int i = head[now]; i != -1; i = edge[i].next)
    {
        to = edge[i].to;
        if (p[to] == -1)
        {
            p[to] = p[now]^edge[i].val;
            dfs(to);
        }
    }
}

void input()
{
    initEdge();
    memset(p, -1, sizeof(p));
    int u, v, w;
    for (int i = 1; i < n; ++i)
    {
        scanf("%d%d%d", &u, &v, &w);
        addEdge(u, v, w);
        addEdge(v, u, w);
    }
    p[0] = 0;
    dfs(0);
}

void work()
{
    int ans = 0;
    initTree();
    for (int i = 0; i < n; ++i)
    {
        add(p[i]);
        ans = max(ans, p[i]^query(p[i]));
    }
    printf("%d\n", ans);
}

int main()
{
    //freopen("test.in", "r", stdin);
    while (scanf("%d", &n) != EOF)
    {
        input();
        work();
    }
    return 0;
}
View Code

 

ACM学习历程—POJ 3764 The xor-longest Path(xor && 字典树 && 贪心)

标签:

原文地址:http://www.cnblogs.com/andyqsmart/p/4957266.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!