poj3321 Apple Tree

来源:互联网 发布:钢结构制图软件 编辑:程序博客网 时间:2024/05/17 16:46


题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=10486

题意:给你一棵树,树上有n个苹果,然后有m个操作,操作包括两类,第一是摘到苹果或者放上苹果,第二是求某个节点枝叶上有几个苹果

思路:dfs深搜+树状数组

dfs深搜还是按照之前用链表构造树的方法来处理。

对一棵树进行深搜,然后将深搜的顺序重新标上号,然后放到一个数组中,记下每一个枝子得起始点和终结点,然后就可以用树状数组了。

我们知道1是主干,深搜的顺序是1 4 6 5 7 2 3当然这也是根据题目的输入建的广义表。

那么当我们深搜的时候就可以在下面标上:

1 4 6 5 7 2 3 (广义表里面的东西,深搜结果)

1 2 3 4 5 6 7num数组我们求和要用的)

这样就是树状数组了。

我们用l1=1r1=7代表1以上的树枝为1-7,也就是所有

l2=6r2 = 7 代表2以上的树枝是 3

同理

l4=2 r4 = 5这样我们就知道4上面的树枝了

每一个树枝在numn】总数组中的位置,这样我们就可以计算啦。。。树状数组,和上面将的一样了,成功转换

具体键代码,main函数主要建广义表,dfs主要是找到每一个树枝在num【n】数组中的起点和终点并记录在l和r数组中。

代码:

#include <iostream>#include <cstdio>#include<string.h>#define maxn 100001using namespace std;int n,m;int c[maxn];int head[maxn];int id[maxn],a[maxn];int l[maxn],r[maxn];int index;int idx;struct edge{   int to,next;}e[maxn];//链表,和匈牙利算法的写法类似void addedge(int a,int b)//向图中加边的算法,注意加上的是有向边{    e[index].to=b;    e[index].next=head[a];    head[a]=index;    index++;}int lowbit(int a){    return a&(-a);}void update(int i,int x){    while(i<=n)    {        c[i]+=x;        i+=lowbit(i);    }}int getsum(int i){    int sum=0;    while(i>0)    {        sum+=c[i];        i-=lowbit(i);    }    return sum;}//深度搜索,然后用id按顺序标记,//l数组和r数组记录的是搜索开始的地点,和最深的地点void dfs(int u){  id[u]=++idx;  l[u]=idx;  for(int i=head[u];i!=-1;i=e[i].next)    dfs(e[i].to);    r[u]=idx;}int main(){    int s,e;    char ch;    int u;    scanf("%d",&n);    memset(head,-1,sizeof(head));    memset(a,1,sizeof(a));    index=0;    for(int i=0;i<n-1;i++)    {        scanf("%d%d",&s,&e);        addedge(s,e);    }    dfs(1);    //for(int i=1;i<=n;i++)cout<<l[i]<<" "<<r[i]<<endl;    for(int i=1;i<=n;i++)    {        update(i,1);    }    scanf("%d",&m);    while(m--)    {        getchar();        scanf("%c%d",&ch,&u);        if(ch=='C')        {            if(a[u])            {                a[u]=0;                update(id[u],-1);            }            else            {                a[u]=1;                update(id[u],1);            }        }        else        printf("%d\n",getsum(r[u])-getsum(l[u]-1));    }    return 0;}


 

0 0
原创粉丝点击