poj3764 The XOR Longest Path【dfs】【Trie树】

The xor-longest Path

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 10038   Accepted: 2040

Description

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:

⊕ 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 uand 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)

Source

题意:

给一棵带边权的树,想找得到两个点,他们的路径上的权值异或最小。

思路:

首先我们任意找一个作为根,可以用dfs求出其他节点到根的路径的异或,记为xordis

那么对于树上的任意两个节点i, j,i到j的路径的异或和应该是xordis[i] ^ xordis[j]

因为i到j的路径,相当于i到根,根到j,其中重叠的部分,他们的异或值正好是0

因此这道题就变成了找两点异或值最小,https://www.cnblogs.com/wyboooo/p/9824293.html 和这道题就差不多了

最后还需要注意,search找到的最大值是除根以外的,还需要和xordis比较一下,取较大值。

  1 #include <iostream>
  2 #include <set>
  3 #include <cmath>
  4 #include <stdio.h>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <map>
  8 using namespace std;
  9 typedef long long LL;
 10 #define inf 0x7f7f7f7f
 11
 12 int n;
 13 const int maxn = 1e5 + 5;
 14 struct edge{
 15     int v, w;
 16     int nxt;
 17 }e[maxn * 2];
 18 int head[maxn], tot = 0;
 19 int xordis[maxn];
 20 int trie[maxn * 32 + 5][3], treetot = 1;
 21
 22 void addedge(int u, int v, int w)
 23 {
 24     e[tot].v = v;
 25     e[tot].w = w;
 26     e[tot].nxt = head[u];
 27     head[u] = tot++;
 28     e[tot].v = u;
 29     e[tot].w = w;
 30     e[tot].nxt = head[v];
 31     head[v] = tot++;
 32 }
 33
 34 void dfs(int rt, int fa)
 35 {
 36     for(int i = head[rt]; i != -1; i = e[i].nxt){
 37         int v = e[i].v;
 38         if(v == fa)continue;
 39         xordis[v] = xordis[rt] ^ e[i].w;
 40         dfs(v, rt);
 41     }
 42 }
 43
 44 void init()
 45 {
 46     memset(head, -1, sizeof(head));
 47     tot = 0;
 48     memset(xordis, 0, sizeof(xordis));
 49     memset(trie, 0, sizeof(trie));
 50 }
 51
 52 void insertt(int x)
 53 {
 54     int p = 1;
 55     for(int i = 30; i >= 0; i--){
 56         int ch = x >> i & 1;
 57         if(trie[p][ch] == 0){
 58             trie[p][ch] = ++tot;
 59         }
 60         p = trie[p][ch];
 61     }
 62 }
 63
 64 int searchh(int x)
 65 {
 66     int p = 1, ans = 0;
 67     for(int i = 30; i >= 0; i--){
 68         int ch = x >> i & 1;
 69         if(trie[p][ch ^ 1]){
 70             p = trie[p][ch ^ 1];
 71             ans |= 1 << i;
 72         }
 73         else{
 74             p = trie[p][ch];
 75         }
 76     }
 77     return ans;
 78 }
 79
 80 int main()
 81 {
 82     while(scanf("%d", &n) != EOF){
 83         init();
 84         for(int i = 0; i < n - 1; i++){
 85             int u, v, w;
 86             scanf("%d%d%d", &u, &v, &w);
 87             addedge(u, v, w);
 88         }
 89         dfs(0, -1);
 90
 91         /*for(int i = 0; i < n; i++){
 92             printf("%d\n", xordis[i]);
 93         }*/
 94
 95         int ans = 0;
 96         for(int i = 1; i < n; i++){
 97             insertt(xordis[i]);
 98             //cout<<searchh(xordis[i])<<endl;
 99             ans = max(ans, searchh(xordis[i]));
100             ans = max(ans, xordis[i]);
101         }
102         printf("%d\n", ans);
103     }
104     return 0;
105 }

原文地址:https://www.cnblogs.com/wyboooo/p/9824427.html

时间: 2024-08-25 12:33:34

poj3764 The XOR Longest Path【dfs】【Trie树】的相关文章

BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对dfs序建可持久化的trie树.这样做的空间复杂度是O(nw),时间复杂度是O(nw). 代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=102000; 5 6 int n,q; 7 int v[maxn

51nod 1295 XOR key (可持久化Trie树)

1295 XOR key  题目来源: HackerRank 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 160 难度:6级算法题 给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求A[L] 至 A[R] 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少? Input 第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= 

POJ 3764 - The xor-longest Path - [DFS+字典树变形]

题目链接:http://poj.org/problem?id=3764 Time Limit: 2000MS Memory Limit: 65536K Description 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) = \bigoplus_{e \in p}w(e)$ $\oplus$

[POJ] #1003# 487-3279 : 桶排序/字典树(Trie树)/快速排序

一. 题目 487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 274040   Accepted: 48891 Description Businesses like to have memorable telephone numbers. One way to make a telephone number memorable is to have it spell a memorable word or

【POJ3764】The xor-longest Path Trie树+异或性质

#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/43486733"); } 题意: 多组数据. 给你一颗树, 然后求一条最长异或路径, 异或路径长度定义为两点间简单路径上所有边权的异或和. 题解: 首先无根树转有根树再在树上跑一遍算出每个点到根的异或和. 然后两点间异或路径长度就是a[i]*

Trie树 + DFS - CSU 1457 Boggle

Boggle Problem's Link: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1457 Mean: 给定n个串,有m个询问. 每个询问给你一个4*4的字符矩阵,你可以在这个字符矩阵中任意字符出发,向四个方向走(已走过的不可重复走),走出一个字符串. 如果n个串中有对应的串和走出的字符串相同,那么需要求出: 1.不同长度的串给了不同的权值,n个串中出现的串的总权值是多少? 2.从出现的字符串中找一个最长的出来,如果有多个,找一个字典

usaco6.1-Cow XOR:trie树

Cow XOR Adrian Vladu -- 2005 Farmer John is stuck with another problem while feeding his cows. All of his N (1 ≤ N ≤ 100,000) cows (numbered 1..N) are lined up in front of the barn, sorted by their rank in their social hierarchy. Cow #1 has the highe

HDU 5269 ZYB loves Xor I( 01 Trie 树)

题目链接:传送门 题意: 求 for i: 1~n  forj:1~n lowbit(a[i]^a[j]) lowbit(x)表示取x的最低位1. lowbit(3)=1    lowbit(6)=2; 分析: 因为其中有一个异或运算,我们就先来分析这个异或运算.发现如果lowbit(x^y) = 2^p; 那么把x^y转化成2进制后他们的前p-1位一定是相同的.那么思路就来了把所有的数字转换 成01字符串,注意要使他们的长度都相等,然后建一颗trie树.然后遍历的时候如果同时 有左右孩子的话那

Luogu_P2536 [AHOI2005]病毒检测 trie树+dfs

Luogu_P2536 [AHOI2005]病毒检测 ### trie树+dfs 题目链接 这两个符号比较有意思 可以把所有的串都先建到trie树上 然后用病毒的模式串在上面搜索 处理这两个符号就可以通过搜索次序解决 主要可以看代码 问的是非病毒,WA了 一个符号可以不取,又WA了 代码如下: #include<bits/stdc++.h> using namespace std; string bd,w[1010]; int ans,n,trie[250010][10],tot=1,ed[2