标签:
//给一棵树 //对任意的s //问有多少对(u,v)是的从u到v的路径的所有边权值为s //f(u,v) = f(root , u)^f(root ,v) //只要记录所有点到树根的路径的异或值 //然后枚举端点 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 1e5+10 ; typedef long long ll ; int nedge ; int vis[maxn] ; int Hash[maxn<<1] ; int dp[maxn] ; struct Edge { int v ;int w ; int next ; }edge[maxn<<1] ; int head[maxn] ; void addedge(int u , int v , int w) { edge[nedge].v = v ; edge[nedge].w = w ; edge[nedge].next = head[u] ; head[u] = nedge++ ; } void dfs(int u , int sum ,int pre) { for(int i = head[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].v ; if(v == pre)continue ; dp[v] = sum^edge[i].w ; Hash[dp[v]]++ ; dfs(v , dp[v] , u ) ; } } int main() { //freopen("in.txt" , "r" , stdin ) ; int n ; int t ; scanf("%d" , &t) ; while(t--) { memset(vis , 0 , sizeof(vis)) ; memset(Hash , 0 , sizeof(Hash)) ; memset(head , -1 , sizeof(head)) ; nedge = 0 ; scanf("%d" , &n) ; for(int i = 1;i < n;i++) { int u , v , w ; scanf("%d%d%d" , &u , &v , &w) ; addedge(u , v , w) ; addedge(v , u , w) ; vis[v] = 1 ; } Hash[0] = 1 ; dp[1] = 0 ; dfs(1 , 0 , -1) ; int q ; scanf("%d" , &q) ; while(q--) { int s ; scanf("%d" , &s) ; ll ans = 0 ; for(int i = 1;i <= n;i++) { int tmp = dp[i]^s ; ans += (ll)Hash[tmp] ; } if(s) cout<<ans/2<<endl ; else cout<<(ans+(ll)n)/2<<endl; } } return 0 ; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/cq_pf/article/details/48109773