zoukankan      html  css  js  c++  java
  • Hdu 5416 CRB and Tree (bfs)

    题目链接:

      Hdu 5416 CRB and Tree

    题目描述:

      给一棵树有n个节点,树上的每条边都有一个权值。f(u,v)代表从u到v路径上所有边权的异或值,问满足f(u,v)==m的(u, v)有多少中情况(u, v有可能相同)?

    解题思路:

      由于xor的特殊性质。x^x=0,对于求f(u, v) == f(u, 1) ^ f(1, u)。 又因为x^y == z可以推出x^z == y,对于f(u, 1) ^ f(1, v) == m可以转化为m ^ f(1, v) == f(u, 1)。

      可以先遍历一遍树,然后记录下来根节点到每个节点所经过路径的xor值,hash保存xor值出现的次数,然后枚举节点v即可。复杂度O(n*q)

      hash表要开到pow(2,18)左右,如果小的话会wa。

     1 #include <queue>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 typedef long long LL;
     9 const int maxn = 300000;
    10 struct node
    11 {
    12     int to, next, w;
    13 }edge[maxn];
    14 
    15 int arr[maxn], ans[maxn];
    16 int head[maxn], tot;
    17 
    18 void Add (int from, int to, int w)
    19 {
    20     edge[tot].to = to;
    21     edge[tot].w = w;
    22     edge[tot].next = head[from];
    23     head[from] = tot++;
    24 }
    25 void bfs ()
    26 {
    27     queue <int> Q;
    28     Q.push(1);
    29     arr[1] = 0;
    30     while (!Q.empty())
    31     {
    32         int u = Q.front ();
    33         Q.pop();
    34         for (int i=head[u]; i!=-1; i=edge[i].next)
    35         {
    36             int v = edge[i].to;
    37             if (arr[v] == -1)
    38             {
    39                 arr[v] = arr[u] ^ edge[i].w;
    40                 Q.push(v);
    41             }
    42         }
    43     }
    44 }
    45 
    46 int main ()
    47 {
    48     int t, n, q, m;
    49     scanf ("%d", &t);
    50     while (t --)
    51     {
    52         memset (head, -1, sizeof(head));
    53         memset (ans, 0, sizeof(ans));
    54         memset (arr, -1, sizeof(arr));
    55         tot = 0;
    56 
    57         scanf ("%d", &n);
    58         for (int i=1; i<n; i++)
    59         {
    60             int x, y, z;
    61             scanf ("%d %d %d", &x, &y, &z);
    62             Add (x, y, z);
    63             Add (y, x, z);
    64         }
    65 
    66         bfs ();
    67         for (int i=1; i<=n; i++)
    68             ans[arr[i]] ++;
    69 
    70         scanf ("%d", &q);
    71         while (q --)
    72         {
    73             LL res = 0;
    74             scanf ("%d", &m);
    75             for (int i=1; i<=n; i++)
    76                 res += ans[m^arr[i]];
    77             if (m == 0)
    78                 res += n;
    79             printf ("%lld
    ", res/2);
    80         }
    81     }
    82     return 0;
    83 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    svn的revert、checkout、clean up、setting
    jsonp跨域原理
    王亚伟北大演讲:一切通胀问题都是货币问题(全文)
    string <-> wstring
    点在多边形内 经典算法(转)
    不可不表的OSG智能指针之强指针与弱指针 《转载》
    一个shell脚本给客户使用服务器生成一个序列号
    Rsync(远程同步): linux中Rsync命令的实际示例
    一个 rsync同步文件脚本
    用UltraISO制作CentOS U盘安装盘
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4747356.html
Copyright © 2011-2022 走看看