zoukankan      html  css  js  c++  java
  • 18.12.17 DSA The xor-longest Path

    描述

    In an edge-weighted tree, the xor-length of a path pis 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?  

    输入

    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.

    输出

    For each test case output the xor-length of the xor-longest path.

    样例输入

    4
    0 1 3
    1 2 4
    1 3 6
    

    样例输出

    7

    提示

    The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)

      1 #include < algorithm >
      2 #include < cstdio >
      3 #include < cstring >
      4 #include < vector >
      5 using namespace std;
      6 
      7 const int MAXN = 100010;
      8 const int MAXM = 200010;
      9 struct Trie {
     10     Trie *children[2];
     11     int value;
     12 } root, pool[MAXN << 5], *ptr, emptyNode;
     13 // Trie树是一棵二叉树,左孩子表示当前二进制位为0,右孩子表示当前二进制位为1
     14 // 叶子节点额外保存value,表示当前路径对应的数,如根-左-右-右这个节点的value为(011)2=3
     15 
     16 int n;
     17 // 节点个数
     18 
     19 int head[MAXN], succeed[MAXM], vertex[MAXM], weight[MAXM], now;
     20 // head,succeed使用链表保存边表;vertex,weight存每条边的终点以及权值
     21 
     22 int rootXor[MAXN];
     23 // 每个点到根的路径的xor值
     24 
     25 void addEdge(int u, int v, int w) {
     26     // 往链表中添加一条u->v,权值为w的边
     27     ________(1)________
     28     // 新的节点的后继为u节点原来的链表头
     29     vertex[now] = v;
     30     // 新的边的终点为v
     31     weight[now] = w;
     32     // 新的边的权值为w
     33     head[u] = now++;
     34     // 指定u节点新的链表头为now
     35 }
     36 
     37 void readTree() {
     38     // 读入树
     39     memset(head, -1, sizeof head);
     40     now = 0;
     41     for (int i = 0; i < n - 1; i++) {
     42         int u, v, w;
     43         scanf("%d%d%d", &u, &v, &w);
     44         addEdge(u, v, w);
     45         addEdge(v, u, w);
     46     }
     47 }
     48 
     49 void DFS(int x = 0, int father = -1) {
     50     // DFS求出每个点到0号点的路径的xor值,并填到rootXor数组中
     51     // 参数x表示当前递归到的节点,father表示当前点的父亲
     52     for (int now = head[x]; now != -1; now = succeed[now]) {
     53         // 遍历x节点的链表,找到所有x的出边
     54         int y = vertex[now];
     55         int w = weight[now];
     56         // 从x到y有一条权值为w的边
     57         if (________(2)________)
     58             continue;
     59         // 忽略返回父亲的边
     60         rootXor[y] = ________(3)________;
     61         // 计算rootXor[y]的值,为y到0号点的路径的xor值
     62         DFS(y, x);
     63     }
     64 }
     65 
     66 int getNthBit(int value, int nBit) {
     67     return value >> nBit & 1;
     68 }
     69 
     70 void insertTrie(Trie *node, int value, int nBit) {
     71     // 往Trie中插入value
     72     // 当前在node这个节点,处理到value的第nBit个bit
     73     // 如果nBit为-1,说明已经处理完毕,node为叶子节点
     74     if (nBit == -1)
     75         node->value = ________(4)________;
     76     else {
     77         bool bit = ________(5)________;
     78         // bit为0说明当前的节点应为node的左孩子
     79         // bit为1说明当前的节点应为node的右孩子
     80         if (!node->children[bit]) {
     81             node->children[bit] = ptr++;
     82             *node->children[bit] = emptyNode;
     83         }
     84         insertTrie(node->children[bit], value, nBit - 1);
     85     }
     86 }
     87 
     88 void buildTrie() {
     89     // 将所有rootXor[i]插入Trie中
     90     root = emptyNode;
     91     ptr = pool;
     92     for (int i = 0; i < n; i++)
     93         insertTrie(&root, rootXor[i], 30);
     94 }
     95 
     96 int queryTrie(Trie *node, int value, int nBit) {
     97     // 在Trie中查询与value的xor值最大的答案
     98     // 当前在node这个节点,处理到value的第nBit个bit
     99     // 如果nBit为-1,说明已经处理完毕,node为叶子节点
    100     if (nBit == -1)
    101         return node->value ^ value;
    102     else {
    103         bool bit = ________(5)________;
    104         // 同上
    105         if (node->children[!bit])
    106             return queryTrie(node->children[!bit], value, nBit - 1);
    107         else
    108             return queryTrie(node->children[bit], value, nBit - 1);
    109     }
    110 }
    111 
    112 int getAns() {
    113     // 将所有rootXor[i]在Trie中查询最大的xor答案
    114     int ans = 0;
    115     for (int i = 0; i < n; i++)
    116         ans = max(ans, queryTrie(&root, rootXor[i], 30));
    117     return ans;
    118 }
    119 
    120 int main() {
    121     while (scanf("%d", &n) == 1) {
    122         readTree();
    123         DFS();
    124         buildTrie();
    125         printf("%d
    ", getAns());
    126     }
    127     return 0;
    128 }

    填空答案:

      1 #include <iostream>
      2 #include <string.h>
      3 #include <algorithm>
      4 #include <stack>
      5 #include <string>
      6 #include <math.h>
      7 #include <queue>
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <set>
     11 #include <vector>
     12 #include <fstream>
     13 #define maxn 400005
     14 #define inf 999999
     15 #define cha 127
     16 using namespace std;
     17 
     18 const int MAXN = 100010;
     19 const int MAXM = 200010;
     20 struct Trie {
     21     Trie *children[2];
     22     int value;
     23 } root, pool[MAXN << 5], *ptr, emptyNode;
     24 // Trie树是一棵二叉树,左孩子表示当前二进制位为0,右孩子表示当前二进制位为1
     25 // 叶子节点额外保存value,表示当前路径对应的数,如根-左-右-右这个节点的value为(011)2=3
     26 
     27 int n;
     28 // 节点个数
     29 
     30 int head[MAXN], succeed[MAXM], vertex[MAXM], weight[MAXM], now;
     31 // head,succeed使用链表保存边表;vertex,weight存每条边的终点以及权值
     32 
     33 int rootXor[MAXN];
     34 // 每个点到根的路径的xor值
     35 
     36 void addEdge(int u, int v, int w) {
     37     // 往链表中添加一条u->v,权值为w的边
     38     succeed[now] = head[u];
     39         // 新的节点的后继为u节点原来的链表头
     40         vertex[now] = v;
     41     // 新的边的终点为v
     42     weight[now] = w;
     43     // 新的边的权值为w
     44     head[u] = now++;
     45     // 指定u节点新的链表头为now
     46 }
     47 
     48 void readTree() {
     49     // 读入树
     50     memset(head, -1, sizeof head);
     51     now = 0;
     52     for (int i = 0; i < n - 1; i++) {
     53         int u, v, w;
     54         scanf("%d%d%d", &u, &v, &w);
     55         addEdge(u, v, w);
     56         addEdge(v, u, w);
     57     }
     58 }
     59 
     60 void DFS(int x = 0, int father = -1) {
     61     // DFS求出每个点到0号点的路径的xor值,并填到rootXor数组中
     62     // 参数x表示当前递归到的节点,father表示当前点的父亲
     63     for (int now = head[x]; now != -1; now = succeed[now]) {
     64         // 遍历x节点的链表,找到所有x的出边
     65         int y = vertex[now];
     66         int w = weight[now];
     67         // 从x到y有一条权值为w的边
     68         if (y==father)
     69             continue;
     70         // 忽略返回父亲的边
     71         rootXor[y] = rootXor[x]^w;
     72         // 计算rootXor[y]的值,为y到0号点的路径的xor值
     73         DFS(y, x);
     74     }
     75 }
     76 
     77 int getNthBit(int value, int nBit) {
     78     return value >> nBit & 1;
     79 }
     80 
     81 void insertTrie(Trie *node, int value, int nBit) {
     82     // 往Trie中插入value
     83     // 当前在node这个节点,处理到value的第nBit个bit
     84     // 如果nBit为-1,说明已经处理完毕,node为叶子节点
     85     if (nBit == -1)
     86         node->value = value;
     87     else {
     88         bool bit = getNthBit(value, nBit);
     89         // bit为0说明当前的节点应为node的左孩子
     90         // bit为1说明当前的节点应为node的右孩子
     91         if (!node->children[bit]) {
     92             node->children[bit] = ptr++;
     93             *node->children[bit] = emptyNode;
     94         }
     95         insertTrie(node->children[bit], value, nBit - 1);
     96     }
     97 }
     98 
     99 void buildTrie() {
    100     // 将所有rootXor[i]插入Trie中
    101     root = emptyNode;
    102     ptr = pool;
    103     for (int i = 0; i < n; i++)
    104         insertTrie(&root, rootXor[i], 30);
    105 }
    106 
    107 int queryTrie(Trie *node, int value, int nBit) {
    108     // 在Trie中查询与value的xor值最大的答案
    109     // 当前在node这个节点,处理到value的第nBit个bit
    110     // 如果nBit为-1,说明已经处理完毕,node为叶子节点
    111     if (nBit == -1)
    112         return node->value ^ value;
    113     else {
    114         bool bit = getNthBit(value,nBit);
    115         // 同上
    116         if (node->children[!bit])
    117             return queryTrie(node->children[!bit], value, nBit - 1);
    118         else
    119             return queryTrie(node->children[bit], value, nBit - 1);
    120     }
    121 }
    122 
    123 int getAns() {
    124     // 将所有rootXor[i]在Trie中查询最大的xor答案
    125     int ans = 0;
    126     for (int i = 0; i < n; i++)
    127         ans = max(ans, queryTrie(&root, rootXor[i], 30));
    128     return ans;
    129 }
    130 
    131 int main() {
    132     while (scanf("%d", &n) == 1) {
    133         readTree();
    134         DFS();
    135         buildTrie();
    136         printf("%d
    ", getAns());
    137     }
    138     return 0;
    139 }
    View Code
    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    hibernate常用配置
    hibernate快速入门
    【转】Struts2中json插件的使用
    【转】Struts2解决表单重复提交问题
    OGNL表示式使用和值栈
    Python就是为了方便生活,比如看VIP电影
    使用python进行面部合成,比PS好用多了
    Python黑科技,教你学会Django系统错误监控
    Python这么厉害的么?一次爬完整站小说
    Linux优化不知如何下手?那你的看看这篇文章了
  • 原文地址:https://www.cnblogs.com/yalphait/p/10132788.html
Copyright © 2011-2022 走看看