HDU 5416 dfs
阿新 • • 發佈:2019-01-21
題意:給一個樹和樹上的邊權,然後Q個詢問,每次詢問樹上的不同點對的路徑異或值為s
思路:因為a^b==c則a^c==b,所以我們以1為根建樹,然後每個節點儲存1到自己的異或值,然後每一個異或值都記錄個數,最後詢問的時候就遍歷所有的點為結尾,然後看一下有多少個出現過,但是會算兩遍,然後就是注意s==0的情況
#include <vector> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3fll; const int maxn=100010; int num[2*maxn],vis[maxn],dis[maxn],kkk,head[maxn]; struct node{ int to,next,cost; }EE[2*maxn]; void add_edge(int u,int v,int cost){ EE[kkk].to=v;EE[kkk].cost=cost;EE[kkk].next=head[u];head[u]=kkk++; } void dfs(int u,int fa,int ddd){ num[ddd]++;dis[u]=ddd; for(int i=head[u];i!=-1;i=EE[i].next){ int v=EE[i].to; if(v==fa) continue; int lll=ddd^EE[i].cost; dfs(v,u,lll); } } int main(){ int T,n,u,v,c,q; scanf("%d",&T); while(T--){ scanf("%d",&n);kkk=0; memset(head,-1,sizeof(head)); memset(num,0,sizeof(num)); for(int i=0;i<n-1;i++){ scanf("%d%d%d",&u,&v,&c); add_edge(u,v,c); add_edge(v,u,c); } dfs(1,0,0); scanf("%d",&q); while(q--){ scanf("%d",&u); ll ans=0; for(int i=1;i<=n;i++){ int ttt=u^dis[i]; if(u==0) ans+=(num[ttt]-1); else ans+=num[ttt]; } if(u==0) ans+=2*n; printf("%I64d\n",ans/2); } } return 0; }