• 最长异或路径 ---- (字典树求异或最大)


    目录

    最长异或路径:

    题目大意:

    思路解析:

    代码实现:


    最长异或路径:

    题目大意:

    思路解析:

    现在假设有一棵这样的树,我们并不关心每条边的路径权值为多少,假设划红线的地方是异或值最大的一条路径,那我们可以发现我们只需要知道1-11的异或值,1-7路径的异或值,那我们在贪心的过程一定能得到最优答案

     

    第二种情况,最大异或路径不经过顶点,但是我们发现 11 ^ 5 ^ 6 ^ 13 ^ 14等价于(2 ^ 5 ^ 11) ^ (  2 ^ 6 ^ 13 ^ 14) ,可以发现还是相当于1--11的路径异或1-14的路径,所以我们只需要得到顶点到其他任意结点的路径即可,那我们在贪心选择时一定能得到最优解。

     

     

    现在得到顶点到其他任意结点的异或路径值后,我们应该考虑我们如何贪心的选择。

    假设我们现在路径的异或值为 2,曾经到过的路径异或值有(5 ,4,3,6)他们的二进制数分布为010,101,100,011,110,我们发现我们与5的路径异或后能得到最优答案。那么贪心选择为从二进制位的高位开始抉择,如果能有一个数能和当前值异或后在该位为1就选择这个数。

    但是如果我们进行遍历选择,就会时间复杂度过高,那我们可以使用01字典树,这样就可以每次筛去大部分结果。

    代码实现:

    1. import java.io.*;
    2. import java.util.*;
    3. import static java.lang.String.*;
    4. public class Main {
    5. static int MAXN = 100010;
    6. static int n;
    7. static int[][] tree = new int[MAXN << 3][2];
    8. static int[] nxt = new int[MAXN << 1];
    9. static int[] head = new int[MAXN];
    10. static int[] to = new int[MAXN << 1];
    11. static int[] weight = new int[MAXN << 1];
    12. static int tot = 0;
    13. static int ans = 0;
    14. static int cnt;
    15. static int[] dp = new int[MAXN];
    16. public static void main(String[] args) throws IOException {
    17. FastScanner f = new FastScanner();
    18. PrintWriter w = new PrintWriter(System.out);
    19. n = f.nextInt();
    20. for (int i = 0; i < n - 1; i++) {
    21. int x = f.nextInt();
    22. int y = f.nextInt();
    23. int v = f.nextInt();
    24. add(x, y, v);
    25. add(y,x,v);
    26. }
    27. dfs(1, 0);
    28. w.println(ans);
    29. w.flush();
    30. w.close();
    31. }
    32. static void dfs(int x, int fa){
    33. insert(dp[x]);
    34. get(dp[x]);
    35. for (int i = head[x]; i != 0; i = nxt[i]) {
    36. int y = to[i];
    37. if (y == fa) continue;
    38. dp[y] = dp[x] ^ weight[i];
    39. dfs(y, x);
    40. }
    41. }
    42. static void insert(int x){
    43. int p = 0;
    44. for(int i = 30; i >= 0; i--){
    45. int c = ((x >> i) & 1);
    46. if (tree[p][c] == 0){
    47. tree[p][c] = ++cnt;
    48. }
    49. p = tree[p][c];
    50. }
    51. }
    52. static void get(int x){
    53. int res = 0;
    54. int p = 0;
    55. for (int i = 30; i >= 0; i--) {
    56. int c = ((x >> i) & 1);
    57. if (tree[p][c ^ 1] != 0){
    58. res |= (1 << i);
    59. p = tree[p][c ^ 1];
    60. }else {
    61. p = tree[p][c];
    62. }
    63. }
    64. ans = Math.max(ans, res);
    65. }
    66. static void add(int x, int y, int v){
    67. nxt[++tot] = head[x];
    68. head[x] = tot;
    69. to[tot] = y;
    70. weight[tot] = v;
    71. }
    72. private static class FastScanner {
    73. final private int BUFFER_SIZE = 1 << 16;
    74. private DataInputStream din;
    75. private byte[] buffer;
    76. private int bufferPointer, bytesRead;
    77. private FastScanner() throws IOException {
    78. din = new DataInputStream(System.in);
    79. buffer = new byte[BUFFER_SIZE];
    80. bufferPointer = bytesRead = 0;
    81. }
    82. private short nextShort() throws IOException {
    83. short ret = 0;
    84. byte c = read();
    85. while (c <= ' ') c = read();
    86. boolean neg = (c == '-');
    87. if (neg) c = read();
    88. do ret = (short) (ret * 10 + c - '0');
    89. while ((c = read()) >= '0' && c <= '9');
    90. if (neg) return (short) -ret;
    91. return ret;
    92. }
    93. private int nextInt() throws IOException {
    94. int ret = 0;
    95. byte c = read();
    96. while (c <= ' ') c = read();
    97. boolean neg = (c == '-');
    98. if (neg) c = read();
    99. do ret = ret * 10 + c - '0';
    100. while ((c = read()) >= '0' && c <= '9');
    101. if (neg) return -ret;
    102. return ret;
    103. }
    104. public long nextLong() throws IOException {
    105. long ret = 0;
    106. byte c = read();
    107. while (c <= ' ') c = read();
    108. boolean neg = (c == '-');
    109. if (neg) c = read();
    110. do ret = ret * 10 + c - '0';
    111. while ((c = read()) >= '0' && c <= '9');
    112. if (neg) return -ret;
    113. return ret;
    114. }
    115. private char nextChar() throws IOException {
    116. byte c = read();
    117. while (c <= ' ') c = read();
    118. return (char) c;
    119. }
    120. private String nextString() throws IOException {
    121. StringBuilder ret = new StringBuilder();
    122. byte c = read();
    123. while (c <= ' ') c = read();
    124. do {
    125. ret.append((char) c);
    126. } while ((c = read()) > ' ');
    127. return ret.toString();
    128. }
    129. private void fillBuffer() throws IOException {
    130. bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
    131. if (bytesRead == -1) buffer[0] = -1;
    132. }
    133. private byte read() throws IOException {
    134. if (bufferPointer == bytesRead) fillBuffer();
    135. return buffer[bufferPointer++];
    136. }
    137. }
    138. }

  • 相关阅读:
    玩转堆排序以及Topk问题——【数据结构】
    sparksql broadcast join opt
    缺页中断处理
    c++中的deque容器和queue容器
    动态规划:13目标和
    [Android开发学iOS系列] TableView展现一个list
    深入浅出DAX:数据分析
    Go的方法(method)
    深度学习与总结JVM专辑(一):基础介绍&&内存结构(图文+代码)
    Linux CC++ 网络编程博客
  • 原文地址:https://blog.csdn.net/weixin_73936404/article/details/136485257