HDU 5416 dfs

来源:互联网 发布:友贷资本网络贷款 编辑:程序博客网 时间:2024/05/29 07:52

点击打开链接

题意:给一个树和树上的边权,然后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;}

0 0
原创粉丝点击