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 }
本文为博主原创文章,未经博主允许不得转载。
原文地址:https://www.cnblogs.com/alihenaixiao/p/4747356.html